Compare commits
10 Commits
83b2f94a22
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 78c9c967bb | |||
| ed63c6ea25 | |||
| 8223eba81b | |||
| 659b61a5f0 | |||
| 3975d92651 | |||
| d01f7afe3e | |||
| e38f69eed7 | |||
| fa54a2def0 | |||
| 0f3ca699dc | |||
| c7c64f560d |
@@ -1,2 +1,3 @@
|
||||
x*
|
||||
**.swp
|
||||
log_*
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 fanasina
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,201 @@
|
||||
# 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`
|
||||
|
||||
|
||||
@@ -96,10 +96,114 @@ TEST(lessThan){
|
||||
EXPECT_LT_TYPE_DOUBLE(db,da);
|
||||
}
|
||||
|
||||
IMPLEMENTATION_FMOCK()
|
||||
|
||||
MOCK_FUNC(int, f_mock, (), ())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
EXPECT_MOCK_CALL(int,f_mock, (),false, 2) {
|
||||
EXPECT_EQ_IN_MOCKF(21,21,f_mock);
|
||||
EXPECT_EQ(1,3);
|
||||
EXPECT_EQ(4,4);
|
||||
EXPECT_EQ_IN_MOCKF(23,24,f_mock); return 12;}
|
||||
EXPECT_MOCK_CALL(int,f_mock, (),1, 1) { EXPECT_EQ_IN_MOCKF(23,21,f_mock);return 10;}
|
||||
|
||||
EXPECT_MOCK_CALL(int,f_mock, (),1==2||2<1, 1) {return 18;}
|
||||
EXPECT_MOCK_CALL(int,f_mock, (),1, ININITY_REPS) {return -18;}
|
||||
|
||||
|
||||
TEST(mockf1){
|
||||
INIT_CALLER_MOCK(f_mock);
|
||||
|
||||
for(int i = 0; i<8; ++i){
|
||||
|
||||
LOG("call f_mock:%d: ret:%d\n",i,f_mock());
|
||||
// int val=f_mock();
|
||||
//PRINTF("call f_mock:%d: ret:%d\n",i,val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// //
|
||||
|
||||
MOCK_FUNC(int, f2_mock,(int a,int b),(a,b))
|
||||
|
||||
STR_PRINT_CUR_VAR(f2_mock, (int a,int b),(a,b)){
|
||||
char *ret=malloc(150);
|
||||
//char ret[150];
|
||||
sprintf(ret,"(int)a: %d, (int)b: %d",a,b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), (a<b), 3){
|
||||
return a+b;
|
||||
}
|
||||
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), ((a<b)&&(b<100)), 1){
|
||||
return a*b;
|
||||
}
|
||||
|
||||
WILL_MOCK_CALL(int, f2_mock, (int a,int b), (a!=b), 6){
|
||||
return a/b;
|
||||
}
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), (a==b), 1){
|
||||
return a/b;
|
||||
}
|
||||
|
||||
|
||||
// //
|
||||
|
||||
MOCK_FUNC(int, f3_mock,(int a,int b),(a,b))
|
||||
|
||||
EXPECT_MOCK_CALL(int, f3_mock, (int a,int b), (a<b), 2){
|
||||
return a+b;
|
||||
}
|
||||
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), ((a<b)&&(b<100)), 1){
|
||||
return a*b;
|
||||
}
|
||||
|
||||
WILL_MOCK_CALL(int, f2_mock, (int a,int b), (a!=b), 6){
|
||||
return a/b;
|
||||
}
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), (a==b), 1){
|
||||
return a/b;
|
||||
}
|
||||
|
||||
|
||||
// //
|
||||
|
||||
EXPECT_MOCK_CALL(int, f2_mock, (int a,int b), (1), ININITY_REPS){
|
||||
return a*b;
|
||||
}
|
||||
|
||||
TEST(f2mock_test){
|
||||
INIT_CALLER_MOCK(f2_mock);
|
||||
//LOG("--------------------------- > call f2_mock:%d: %d\n",0,f2_mock(1,4));
|
||||
|
||||
|
||||
for(int i=0; i<8; ++i){
|
||||
|
||||
if(i<2) {
|
||||
//int val = f2_mock(i,4);
|
||||
//LOG("call f2_mock:%d: %d\n",i,val);
|
||||
LOG("call f2_mock:%d: %d\n",i,f2_mock(i,4));
|
||||
|
||||
}
|
||||
else if(i<4) LOG("call:%d: %d\n",i,f2_mock(i,3));
|
||||
else LOG("call:%d:%d\n",i,f2_mock(i,i*i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv){
|
||||
|
||||
//run_all_tests();
|
||||
//run_all_tests_parallel(4);
|
||||
|
||||
|
||||
+1265
-11
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user