From 92dee33c30f58855cb646cdc9d05219954b29b52 Mon Sep 17 00:00:00 2001 From: Austin Ferguson Date: Tue, 19 Sep 2023 20:43:03 -0400 Subject: [PATCH 1/8] Add Catch2 as a dependency --- .gitmodules | 3 +++ third_party/Catch2 | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 third_party/Catch2 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..61932e24 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "third_party/Catch2"] + path = third_party/Catch2 + url = https://github.com/catchorg/Catch2.git diff --git a/third_party/Catch2 b/third_party/Catch2 new file mode 160000 index 00000000..9c541ca7 --- /dev/null +++ b/third_party/Catch2 @@ -0,0 +1 @@ +Subproject commit 9c541ca72e7857dec71d8a41b97e42c2f1c92602 From 68743d703b7338f443e24632674f06f72ce00f7e Mon Sep 17 00:00:00 2001 From: Austin Ferguson Date: Tue, 19 Sep 2023 20:49:57 -0400 Subject: [PATCH 2/8] Add first pass of unit tests --- tests/.gitignore | 6 ++++++ tests/CMakeLists.txt | 15 +++++++++++++++ tests/build/.gitignore | 1 + tests/unit/CMakeLists.txt | 5 +++++ tests/unit/core/CMakeLists.txt | 20 ++++++++++++++++++++ tests/unit/core/Data.cpp | 17 +++++++++++++++++ tests/unit/core/WorldGrid.cpp | 15 +++++++++++++++ tests/unit/core/targets.txt | 2 ++ 8 files changed, 81 insertions(+) create mode 100644 tests/.gitignore create mode 100644 tests/CMakeLists.txt create mode 100644 tests/build/.gitignore create mode 100644 tests/unit/CMakeLists.txt create mode 100644 tests/unit/core/CMakeLists.txt create mode 100644 tests/unit/core/Data.cpp create mode 100644 tests/unit/core/WorldGrid.cpp create mode 100644 tests/unit/core/targets.txt diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 00000000..c09e3d48 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,6 @@ +# Vim swap files +*.swp +*.swo + +# CMake files and directories +CMakeFiles diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 00000000..f2013b5e --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.10) +project(tests VERSION 0.1) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +set(CATCH_SRC_DIR ../third_party/Catch2) +set(CATCH_BUILD_DIR catch_build) +set(MAIN_SOURCE_DIR ../source) + +# Catch2 CMake integration +# From https://github.com/catchorg/Catch2/blob/devel/docs/cmake-integration.md#top +add_subdirectory(${CATCH_SRC_DIR} ${CATCH_BUILD_DIR}) + +add_subdirectory(unit) diff --git a/tests/build/.gitignore b/tests/build/.gitignore new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/tests/build/.gitignore @@ -0,0 +1 @@ +* diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt new file mode 100644 index 00000000..cb96d01a --- /dev/null +++ b/tests/unit/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.10) + + +set(MAIN_SOURCE_DIR ../${MAIN_SOURCE_DIR}) +add_subdirectory(core) diff --git a/tests/unit/core/CMakeLists.txt b/tests/unit/core/CMakeLists.txt new file mode 100644 index 00000000..15af4f55 --- /dev/null +++ b/tests/unit/core/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.10) +#project(tests-unit VERSION 0.1) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +file(STRINGS targets.txt TARGETS) + +set(MAIN_SOURCE_DIR ../${MAIN_SOURCE_DIR}) + +foreach(TARGET IN LISTS TARGETS) + add_executable(tests-unit-core-${TARGET} ${TARGET}.cpp) + + target_include_directories(tests-unit-core-${TARGET} + PRIVATE ${MAIN_SOURCE_DIR} + ) + target_link_libraries(tests-unit-core-${TARGET} + PRIVATE Catch2::Catch2WithMain + ) +endforeach() diff --git a/tests/unit/core/Data.cpp b/tests/unit/core/Data.cpp new file mode 100644 index 00000000..b18d578a --- /dev/null +++ b/tests/unit/core/Data.cpp @@ -0,0 +1,17 @@ +/** + * This file is part of the Fall 2023, CSE 491 course project. + * @brief Unit tests for Data.hpp in source/core + **/ + +// Catch2 +#define CATCH_CONFIG_MAIN +#include + +// Class project +#include "core/Data.hpp" +#include "core/Entity.hpp" +#include "core/AgentBase.hpp" + +TEST_CASE("CellType", "[core]"){ + +} diff --git a/tests/unit/core/WorldGrid.cpp b/tests/unit/core/WorldGrid.cpp new file mode 100644 index 00000000..a954414e --- /dev/null +++ b/tests/unit/core/WorldGrid.cpp @@ -0,0 +1,15 @@ +/** + * This file is part of the Fall 2023, CSE 491 course project. + * @brief Unit tests for Data.hpp in source/core + **/ + +// Catch2 +#define CATCH_CONFIG_MAIN +#include + +// Class project +#include "core/WorldGrid.hpp" + +TEST_CASE("CellType", "[core]"){ + +} diff --git a/tests/unit/core/targets.txt b/tests/unit/core/targets.txt new file mode 100644 index 00000000..773d3a00 --- /dev/null +++ b/tests/unit/core/targets.txt @@ -0,0 +1,2 @@ +Data +WorldGrid From 5400c068f0878f0f106281b29114435d30a1a6e6 Mon Sep 17 00:00:00 2001 From: Austin Ferguson Date: Tue, 19 Sep 2023 20:50:17 -0400 Subject: [PATCH 3/8] Add missing include --- source/core/WorldGrid.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/core/WorldGrid.hpp b/source/core/WorldGrid.hpp index a3405a34..bc8de740 100644 --- a/source/core/WorldGrid.hpp +++ b/source/core/WorldGrid.hpp @@ -15,6 +15,7 @@ #include "CoreObject.hpp" #include "GridPosition.hpp" +#include "Data.hpp" namespace cse491 { @@ -194,4 +195,4 @@ namespace cse491 { }; -} // End of namespace cse491 \ No newline at end of file +} // End of namespace cse491 From 66c7b66151843432e956833a67b21015deb333bc Mon Sep 17 00:00:00 2001 From: Austin Ferguson Date: Tue, 19 Sep 2023 21:03:51 -0400 Subject: [PATCH 4/8] Add unit test workflow --- .github/workflows/unit_tests.yml | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/unit_tests.yml diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml new file mode 100644 index 00000000..65a8025a --- /dev/null +++ b/.github/workflows/unit_tests.yml @@ -0,0 +1,42 @@ +# This is a basic workflow to help you get started with Actions + +name: Build and run unit tests + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the "main" branch + push: + branches: [ "main", "testing" ] + pull_request: + branches: [ "main", "testing" ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - run: sudo apt-get update -qq + - run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + - run: sudo apt-get update -qq + - run: sudo apt-get install -qq cmake build-essential python3-pip python3-virtualenv nodejs tar gzip libpthread-stubs0-dev libc6-dbg gdb + - run: g++ --version + - name: Build tests + run: | + cmake .. + cmake --build . + working-directory: tests/build + - name: Run tests + run: ./tests-unit-core-Data + working-directory: tests/build/unit/core From 2974036c508f9274a5f366a261b634abfd79b507 Mon Sep 17 00:00:00 2001 From: Austin Ferguson Date: Tue, 19 Sep 2023 21:28:50 -0400 Subject: [PATCH 5/8] Add script to run tests --- .github/workflows/unit_tests.yml | 4 ++-- tests/CMakeLists.txt | 2 ++ tests/run_tests.sh | 27 +++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100755 tests/run_tests.sh diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 65a8025a..35aaa0af 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -38,5 +38,5 @@ jobs: cmake --build . working-directory: tests/build - name: Run tests - run: ./tests-unit-core-Data - working-directory: tests/build/unit/core + run: ./run_tests.sh + working-directory: tests/build diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f2013b5e..72b0b6f5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,6 +8,8 @@ set(CATCH_SRC_DIR ../third_party/Catch2) set(CATCH_BUILD_DIR catch_build) set(MAIN_SOURCE_DIR ../source) +configure_file(run_tests.sh run_tests.sh COPYONLY) + # Catch2 CMake integration # From https://github.com/catchorg/Catch2/blob/devel/docs/cmake-integration.md#top add_subdirectory(${CATCH_SRC_DIR} ${CATCH_BUILD_DIR}) diff --git a/tests/run_tests.sh b/tests/run_tests.sh new file mode 100755 index 00000000..a2d51a9a --- /dev/null +++ b/tests/run_tests.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +run_tests () { + local DIR_NAME=$(pwd | grep -oP "/\w+$" | grep -oP "\w+") + local FILENAMES=$(ls tests-unit-* 2> /dev/null) + for FILENAME in ${FILENAMES} + do + echo "Running test: ${FILENAME}" + ./${FILENAME} + done +} + +cd unit +TARGETS="core Agents Worlds Interfaces" +for TARGET in ${TARGETS} +do +if [ -d ${TARGET} ] + then + echo "Entering ${TARGET}" + cd ${TARGET} + run_tests + echo "Exiting ${TARGET}" + else + echo "Directory not found: ${TARGET}. Skipping." + fi +done +cd .. From 0ae49af39ace160db6a4e989f77769e9b88e4c72 Mon Sep 17 00:00:00 2001 From: Austin Ferguson Date: Wed, 20 Sep 2023 11:53:27 -0400 Subject: [PATCH 6/8] Add a few example tests --- tests/unit/core/Data.cpp | 5 ++++- tests/unit/core/WorldGrid.cpp | 38 +++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/tests/unit/core/Data.cpp b/tests/unit/core/Data.cpp index b18d578a..48fcf188 100644 --- a/tests/unit/core/Data.cpp +++ b/tests/unit/core/Data.cpp @@ -13,5 +13,8 @@ #include "core/AgentBase.hpp" TEST_CASE("CellType", "[core]"){ - + cse491::CellType cell_type("name", "desc", '@'); + CHECK(cell_type.name == "name"); + CHECK(cell_type.desc == "desc"); + CHECK(cell_type.symbol == '@'); } diff --git a/tests/unit/core/WorldGrid.cpp b/tests/unit/core/WorldGrid.cpp index a954414e..b8bc6597 100644 --- a/tests/unit/core/WorldGrid.cpp +++ b/tests/unit/core/WorldGrid.cpp @@ -10,6 +10,40 @@ // Class project #include "core/WorldGrid.hpp" -TEST_CASE("CellType", "[core]"){ - +TEST_CASE("WorldGrid Construction", "[core][grid]"){ + SECTION("Default construction"){ + cse491::WorldGrid grid; + CHECK(grid.GetWidth() == 0); + CHECK(grid.GetWidth() == 0); + CHECK(grid.GetNumCells() == 0); + CHECK(!grid.IsValid(0, 0)); + CHECK(!grid.IsValid(1, 1)); + CHECK(!grid.IsValid(-1, -1)); + } + SECTION("Standard construction, no type"){ + cse491::WorldGrid grid(10, 10); + CHECK(grid.GetWidth() == 10); + CHECK(grid.GetWidth() == 10); + CHECK(grid.GetNumCells() == 100); + CHECK(grid.IsValid(0, 0)); + CHECK(grid.IsValid(1, 1)); + CHECK(grid.IsValid(9, 9)); + CHECK(!grid.IsValid(0, 10)); + CHECK(!grid.IsValid(10, 0)); + CHECK(!grid.IsValid(-1, -1)); + } +} +// TODO: Test resizing to a smaller size +// TODO: Check that resizing keeps the cells that are not lost / new +TEST_CASE("WorldGrid Resize", "[core][grid]"){ + SECTION("Resize to larger"){ + cse491::WorldGrid grid; + CHECK(grid.GetWidth() == 0); + CHECK(grid.GetWidth() == 0); + CHECK(grid.GetNumCells() == 0); + grid.Resize(10, 10); + CHECK(grid.GetWidth() == 10); + CHECK(grid.GetWidth() == 10); + CHECK(grid.GetNumCells() == 100); + } } From 3d00795ff6fc9243e5cf420d987316af9e1d6526 Mon Sep 17 00:00:00 2001 From: Austin Ferguson Date: Tue, 26 Sep 2023 13:11:58 -0400 Subject: [PATCH 7/8] Add docs for testing --- docs/HowToTest.md | 99 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 docs/HowToTest.md diff --git a/docs/HowToTest.md b/docs/HowToTest.md new file mode 100644 index 00000000..e80c0a55 --- /dev/null +++ b/docs/HowToTest.md @@ -0,0 +1,99 @@ +This guide will demonstrate how to create, build, and run tests. + +***Note:*** that these instructions should work on Mac and Linux systems. Windows instructions should be similar, but please add any information about working with tests on Windows via a pull request! + +***Note:*** this guide assumes you have Catch2 downloaded. +If you haven't yet downloaded the repo, simply add a `--recursive` to the end of your `git clone`. +If you _have_ downloaded the rest of the repo, simply initialize and update the submodules: +``` +git submodule init +git submodule update +``` + +## How to compile tests + +First, navigate to the `tests` directory. +``` +cd tests +``` + +Create a build directory within `tests`, if it does not already exist. +``` +mkdir build +``` +Note that this will likely through an error/warning if the directory already exists. + +Navigate into the `build` directory. +``` +cd build +``` + +Now we need to use CMake to compile. This is a two step process. +First we tell CMake where to find the files, relative to our current directory. +``` +cmake .. +``` + +If that completes without errors, we can now build the files in our current directory. +``` +cmake --build . +``` + +That should compile the unit tests. +Note that this process will take a while the first time as it needs to compile Catch2. It should be much faster in subsequent builds. + +## Running tests + +If you are on a Mac or Linux system and wish to run _all_ the unit tests, simply run +``` +./run_tests.sh +``` +from _within the `build` directory_ (not just in `tests`). + +If you wish to run a particular test (or are on Windows), simply navigate to the test _within the build directory_. +For example, if we want to run tests for `WorldGrid` (which is in core), we would navigate like so: +``` +cd unit/core +``` + +Once we're in the correct directory, we simply run the executable. +On Unix systems that looks like: +``` +./tests-unit-core-WorldGrid +``` +On Windows it should be similar, though it may have a `.exe` extension. + +## Adding new tests + +To add tests for a new file, navigate to the corresponding folder in the `tests/unit` directory (not in `tests/build`. +For example, if we want to add a test for a new file in `core`, from the root of the repo we would navigate like so: +``` +cd tests/unit/core +``` +Once in the correct directory we need to add the actual source code of the test. +This should be done as a new `.cpp` file, which will typically have the same name as the header file in source (_e.g._, `WorldGrid.hpp` will have a new test file called `WorldGrid.cpp`). + +Once you've created that file, you can start with this skeleton code: + +``` +/** + * This file is part of the Fall 2023, CSE 491 course project. + * @brief + **/ + +// Catch2 +#define CATCH_CONFIG_MAIN +#include + +// Class project +// Place your includes here +// e.g., #include "core/Data.hpp" + +TEST_CASE("NAME", "[tags]"){ +} + +``` + +Finally, once you have some tests coded up, you need to make one more change. +Simply add the name of that file (including the `.cpp`!) to `targets.txt`. +CMake uses this file to ensure we compile the appropriate files. From 33909baff2443198c46c57de363f9ba9592b7031 Mon Sep 17 00:00:00 2001 From: Austin Ferguson Date: Tue, 26 Sep 2023 13:17:17 -0400 Subject: [PATCH 8/8] Add testing link to docs README --- docs/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/README.md b/docs/README.md index 5386d5d3..7c447ff0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,3 +9,5 @@ Below are a set of guides for how to develop your own modules and joining them t - [How to Build an Interface](HowToBuildAnInterface.md) - How to build an interface that allows a human user to control an agent. - [How to Assemble a `main()` function](HowToAssembleAMain.md) - A guide to selecting worlds, agents, and interfaces and turning them into a custom executable (including how to collect data about the resulting system.) + +- [How to build, run, and create unit tests](HowToTest.md) - Walks through how to build and run existing unit tests, as well as create new unit test files.