# Guide to Creating a Test Suite for a New Feature in WAMR This guide provides instructions for contributors on how to create a test suite for a new feature in the WAMR project. Follow these steps to ensure consistency and maintainability across the test framework. --- ## General Guidelines - **Create a New Directory**: Always create a dedicated directory for a new feature under the `tests/unit/` directory. - Reuse existing test cases and patch them when possible to avoid redundancy. - Name the directory in lowercase with words separated by hyphens (e.g., `new-feature`). - Name the test source file in lowercase with words separated by underscore (e.g., `new_test.cc`). - **Avoid Committing `.wasm` Files**: Do not commit precompiled `.wasm` files. Instead: - Generate `.wasm` files from `.wat` or `.c` source files. - Use `ExternalProject` and the `wasi-sdk` toolchain to compile `.wasm` files during the build process. - **Keep Using `ctest` as the framework**: Continue to use `ctest` for running the test cases, as it is already integrated into the existing test framework. --- ## Writing `CMakeLists.txt` for the Test Suite When creating a `CMakeLists.txt` file for your test suite, follow these best practices: 1. **Do Not Fetch Googletest Again**: The root `unit/CMakeLists.txt` already fetches Googletest. Avoid including or fetching it again in your test suite. 2. **Find LLVM on Demand**: If your test suite requires LLVM, use `find_package` to locate LLVM components as needed. Do not include LLVM globally unless required. 3. **Include `unit_common.cmake`**: Always include `../unit_common.cmake` in your `CMakeLists.txt` to avoid duplicating common configurations and utilities. Example: ```cmake include("../unit_common.cmake") ``` 4. **Use `WAMR_RUNTIME_LIB_SOURCE`**: Replace long lists of runtime source files with the `WAMR_RUNTIME_LIB_SOURCE` variable to simplify your configuration. Example: ```cmake target_sources(your_test_target PRIVATE ${WAMR_RUNTIME_LIB_SOURCE}) ``` 5. **Avoid Global Compilation Flags**: Do not define global compilation flags in the `unit` directory. Each test case should specify its own compilation flags based on its unique requirements. --- ## Generating `.wasm` Files - **Compile `.wasm` Files Dynamically**: Use `ExternalProject` in your `CMakeLists.txt` to compile `.wasm` files from `.wat` or `.c` source files. - Use the `wasi-sdk` toolchain for `.c` or `.cc` source files. - Example configuration: ```cmake ExternalProject_Add( generate_wasm SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps BUILD_ALWAYS YES CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps -B build -DWASI_SDK_PREFIX=${WASI_SDK_DIR} -DCMAKE_TOOLCHAIN_FILE=${WASISDK_TOOLCHAIN} BUILD_COMMAND ${CMAKE_COMMAND} --build build INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}/wasm-apps ) ``` - **Example for `wasm-apps` Directory**: Place your source files in a `wasm-apps/` subdirectory within your test suite directory. - Create a `CMakeLists.txt` in `wasm-apps/` to handle the compilation of these files. - Example `CMakeLists.txt` for `wasm-apps/`: ```cmake cmake_minimum_required(VERSION 3.13) project(wasm_apps) add_executable(example example.c) set_target_properties(example PROPERTIES SUFFIX .wasm) install(TARGETS example DESTINATION .) ``` --- ## Compiling and Running Test Cases To compile and run the test cases, follow these steps: 1. **Generate Build Files**: ```bash cmake -S . -B build ``` 2. **Build the Test Suite**: ```bash cmake --build build ``` 3. **Run the Tests**: ```bash ctest --test-dir build --output-on-failure ``` This will compile and execute all test cases in the test suite, displaying detailed output for any failures. 4. **List all Tests**: To see all available test cases, use: ```bash ctest --test-dir build -N ``` 5. **Run a Specific Test**: To run a specific test case, use: ```bash ctest --test-dir build -R --output-on-failure ``` --- ## Collecting Code Coverage Data To collect code coverage data using `lcov`, follow these steps: 1. **Build with Coverage Flags**: Ensure the test suite is built with coverage flags enabled: ```bash cmake -S . -B build -DCOLLECT_CODE_COVERAGE=1 cmake --build build ``` 2. **Run the Tests**: Execute the test cases as described above. 3. **Generate Coverage Report**: Use `lcov` to collect and generate the coverage report: ```bash lcov --capture --directory build --output-file coverage.all.info lcov --extract coverage.all.info "*/core/iwasm/*" "*/core/shared/*" --output-file coverage.info genhtml coverage.info --output-directory coverage-report ``` 4. **View the Report**: Open the `index.html` file in the `coverage-report` directory to view the coverage results in your browser. 5. **Summary of Coverage**: To get a summary of the coverage data, use: ```bash lcov --summary coverage.info ``` --- ## Example Directory Structure Here’s an example of how your test suite directory might look: ``` new-feature/ ├── CMakeLists.txt ├── new_feature_test.cc ├── wasm-apps/ | ├── CMakeLists.txt │ ├── example.c │ └── example.wat ``` --- ## Additional Notes - **Testing Framework**: Use Googletest for writing unit tests. Refer to existing test cases in the `tests/unit/` directory for examples. - **Documentation**: Add comments in your test code to explain the purpose of each test case. - **Edge Cases**: Ensure your test suite covers edge cases and potential failure scenarios. - **Reuse Utilities**: Leverage existing utilities in `common/` (e.g., `mock_allocator.h`, `test_helper.h`) to simplify your test code. --- By following these guidelines, you can create a well-structured and maintainable test suite that integrates seamlessly with the WAMR testing framework.