202 lines
4.0 KiB
Markdown
202 lines
4.0 KiB
Markdown
# y_test_h
|
|
This is a C-only testing library, similar to gtest but written entirely in C.
|
|
|
|
To use it, simply copy the y_test_h.h file into your project, include it in your test files, and use the following macros:
|
|
|
|
-`IMPLEMENTATION_FTEST()` to generate all test functions.
|
|
|
|
-`IMPLEMENTATION_FMOCK()` to generate all mock functions.
|
|
|
|
|
|
# How to create test (ftest)
|
|
## Example
|
|
Example for this file `test.c`:
|
|
```
|
|
C
|
|
```
|
|
```
|
|
#include "y_test_h.h"
|
|
IMPLEMENTATION_FTEST()
|
|
|
|
TEST(nametest){
|
|
EXPECT_EQ(1,1);
|
|
}
|
|
/* allow empty nametest, e.g*/
|
|
TEST(){}
|
|
/* allow duplicate name test, to have suit test */
|
|
TEST(){
|
|
EXPECT_TRUE(true);
|
|
}
|
|
```
|
|
### Requirements
|
|
This program was developed for Linux. It has not been tested on Windows or macOS yet.
|
|
```
|
|
Bash
|
|
```
|
|
```
|
|
$ ls
|
|
test.c y_test_h.h
|
|
```
|
|
|
|
### Compilation
|
|
`gcc -o exectest test.c`
|
|
|
|
Its typically works with `gcc` and `clang`.
|
|
|
|
### Running test
|
|
`./exectest`
|
|
|
|
## The main function
|
|
### Using command-line options:
|
|
```
|
|
C
|
|
```
|
|
```
|
|
int main(int arc, char** argv){
|
|
run_all_tests_args(argc, argv);
|
|
return 0;
|
|
}
|
|
```
|
|
We can add execution option like:
|
|
|
|
`./exectest -h` : Print help
|
|
|
|
`./exectest -p 5` : Parallelize tests using 5 threads.
|
|
|
|
`./exectest` : Run tests sequentially (1 thread).
|
|
|
|
|
|
### Using only sequential tests
|
|
```
|
|
C
|
|
```
|
|
```
|
|
int main(){
|
|
run_all_tests();
|
|
return 0;
|
|
}
|
|
```
|
|
Note: In this case, `./exectest` does not read command-line arguments.
|
|
|
|
### Using only parrallel tests
|
|
```
|
|
C
|
|
```
|
|
```
|
|
int main(){
|
|
run_all_tests_parallel(4); /* to use 4 threads */
|
|
return 0;
|
|
}
|
|
```
|
|
Note: In this case, `./exectest` does not read command-line arguments.
|
|
|
|
# FMOCK
|
|
You can create functions with predefined return values based on specific calls and conditions to simulate the behavior of real functions.
|
|
|
|
## How to create fmock
|
|
```
|
|
C
|
|
```
|
|
```
|
|
#include "y_test_h.h"
|
|
IMPLEMENTATION_FMOCK()
|
|
```
|
|
outside of any function:
|
|
```
|
|
C
|
|
```
|
|
```
|
|
MOCK_FUNC(
|
|
returnType,
|
|
name_function_mock,
|
|
(prototype of the function with paranthesis),
|
|
(args when call the funct with parathesis)
|
|
)
|
|
/* use (returnType) in parathesis if the returType has more than 1 words
|
|
for example (long int) or (struct someStruct) */
|
|
```
|
|
## Example
|
|
To mock a function with the signature `int f_mock(int a,int b);`
|
|
```
|
|
C
|
|
```
|
|
```
|
|
MOCK_FUNC(int, f_mock,(int a,int b),(a,b))
|
|
```
|
|
## Arguments breakdown
|
|
```
|
|
returnType: int,
|
|
function_name: f_mock,
|
|
Prototype: (int a,int b),
|
|
Variables : (a,b)
|
|
```
|
|
## Printing variables
|
|
You can define a function to print the mock function's variables for logging purposes. The macro uses similar arguments to `MOCK_FUNC`, but the return type is always `char*`.
|
|
|
|
Example for `f_mock` :
|
|
```
|
|
C
|
|
```
|
|
```
|
|
STR_PRINT_CUR_VAR(f_mock, (int a,int b),(a,b)){
|
|
char *ret=malloc(150);
|
|
sprintf(ret,"(int)a: %d, (int)b: %d",a,b);
|
|
return ret;
|
|
}
|
|
```
|
|
## Define an expected call
|
|
```
|
|
C
|
|
```
|
|
```
|
|
EXPECT_MOCK_CALL(int, f_mock, (int a,int b), (a<b), 3){
|
|
return a+b;
|
|
}
|
|
```
|
|
### Arguments:
|
|
```
|
|
returnType: int,
|
|
function_name: f_mock,
|
|
Prototype : (int a,int b),
|
|
Condition : (a<b) (boolean expression checked before execution)
|
|
Repetition : 3 (number of times this response is expected)
|
|
```
|
|
## Define a "will" call
|
|
```
|
|
C
|
|
```
|
|
```
|
|
WILL_MOCK_CALL(int, f_mock, (int a,int b), (a==b), 1){
|
|
return a*b;
|
|
}
|
|
```
|
|
The arguments are the same as `EXPECT_MOCK_CALL`. The difference is that `EXPECT_MOCK_CALL` must be triggered during the test, whereas `WILL_MOCK_CALL` is optional.
|
|
|
|
## Initializing and calling mocks
|
|
In a `TEST` environment, you should use the `INIT_CALLER_MOCK(f_mock)`; macro before calling the mock to get explicit logs.
|
|
|
|
Calling a mock function is done exactly like a normal functions.
|
|
|
|
### Example:
|
|
```
|
|
C
|
|
```
|
|
```
|
|
TEST(f_mock_test){
|
|
INIT_CALLER_MOCK(f_mock);
|
|
PRINTF(" first call: %d\n",f_mock(2,3));
|
|
PRINTF(" second call: %d\n",f_mock(3,3));
|
|
}
|
|
```
|
|
# PRINTF
|
|
While you can use the standard `printf`, this library provides a `PRINTF` macro. It allows logs to be recorded in files and ensures that logs remain ordered when running parallel tests.
|
|
|
|
The arguments are identical to the standard `stdio.h` `printf`.
|
|
|
|
```
|
|
PRINTF("hello\n");
|
|
```
|
|
Note : `LOG` is also available as an alias for `PRINTF`
|
|
|
|
|