-
Notifications
You must be signed in to change notification settings - Fork 41
Unit testing suites
Two unit test suites exist within SasView; one to test the calculations performed in the sascalc package and another to test the GUI behavior in the qtgui package. The sascalc unit tests are housed in the test package in the base directory of SasView. The GUI unit tests are housed within each subpackage of the qtgui package in a directories named UnitTesting
.
A successful sasview build requires all GUI and calculation unit tests to pass in Ubuntu but only the calculation tests need to pass in Windows and MacOS. Any new GUI or calculation feature should come with unit tests and all new tests must pass. Any existing tests that are currently succeeding must continue to pass.
For more information on unit testing, please see the wikipedia page on unit tests.
Unit tests for the sascalc package are held within the /test/
directory in the base directory of the sasview repository. Each subdirectory in the test directory houses tests specific to each subpackage in sascalc. There are two scripts available to run the unit tests, one that runs the entire test suite and another that runs tests from a specific test file.
- To run all tests from the base sasview directory:
python test\utest_sasview.py
- To run a single test package from the base sasview directory:
python test\run_one.py <test_package>
. Thetest_package
can be either an absolute path to a python file or a relative path from the location the script was run.
The test runner, utest_sasview.py
, recursively steps through all subdirectories in the /tests/
directory and looks for any files that match the name pattern utest_<test_name>.py
and runs them as python files. Individual files use the unittest package to run their respective unit tests.
To add a new test to an existing python file, simply add a new method starting with the word test
in any class that inherits from unittest.TestCase
. To add a new file with tests, import unittest
, create a class that inherits from unittest.TestCase
, add a method to the class that starts with the word test
, and add if name == '__main__': unittest.main()
at the end of the file. If you would like to run a series of actions before and/or after each test runs, the TestCase
class has a setUp method that will run before each test and a tearDown method that will run after each test completes.
- Importing the unittest package:
import unittest
- Adding a new class of unit tests:
class <testClassName>(unittest.TestCase):
- Adding a new test to an existing class:
def test_<test_name>(self):
- Ensure the test runner runs all tests in the file:
if name == '__main__': unittest.main()
- Run a series of actions before each test starts:
def setUp(self):
- Run a series of actions after each test completes:
def tearDown(self):
Unit tests for the qtgui package are housed within each subpackage and should be specific to that subpackage, e.g. the fitting GUI tests are held in the Perspectives/Fitting/UnitTesting directory. All unit tests are run using pytest
. Pytest recursively searches for files as specified in pytest.ini
, found in the top-most level of the sasview repository.
Running unit tests:
- To run all unit tests:
python -m pytest -v src\sas\qtgui\
- To run a subset of tests:
python -m pytest -v src\sas\qtgui\<path>\<to><subset>
pytests.ini information:
-
norecursedirs
: A space-delimited list of directories that should not be traversed when searching for unit tests. Useful for skipping subdirectories. -
addopts
: Other command line options to always include when running pytest. -
python_files
: A space-delimited list of file name formats that should be included for testing if found during the recursive search. * is used for a catch-all. -
python_classes
: A space-delimited list of class name formats that should be included for testing if found during the recursive search. * is used for a catch-all.
Test files should be stored within the UnitTesting
package within the respective package the test is meant for. GUI tests use the pytest
package and have a different paradigm than the tests for sascalc
. To add a new test to an existing python file, simply add a new method starting with the word test
in any class that matches any pattern in pytest.ini python_classes
. To add a new file with tests, give the file a name that matches any pattern in pytest.ini python_files
, import pytest
in that file, create a class that matches any pattern in pytest.ini python_classes
, and add a method to the class. If you would like to create a common variable used by many tests, add the @pytest.fixture(autouse=True)
decorator to a method, create the common variable in the method, yield <variable>
, and pass the method name as an argument to the tests you would like to use the variable in. Use the assert
statement for testing and equalities. pytest.approx()
can be used for floating point comparisons.
- Importing the pytest package:
import pytest
- Adding a new class of unit tests:
class <testClassName>:
- Adding a new test to an existing class:
def <test_name>(self):
- Use the
assert
statement for testing for True statements and pytest.approx() when comparing floating point values to one-another - Example of an entire test runner:
class MyClassTest:
@pytest.fixture(autouse=True)
def variable(self):
class MyDummyClass:
def __init__(self, number=2):
self._var = number
def integer(self):
return int(self._var)
def floating_point(self):
return float(self._var)
def string(self):
return str(self._var)
def do_something(self):
pass
# create a variable and assign something to it
variable = MyDummyClass()
# Perform a series of class operations that would be common
variable.do_something()
# Return the variable
yield variable
# Destroy the variable
variable.close()
# Use variable in another method
def some_random_test(self, variable):
# variable will now be a MyClass instance and the do_something() method has already run
assert variable.integer == 2
assert pytest.approx(variable.floating_point, 5) == 2.0
assert pytest.string == "2.0"
Many GUI tests currently have the decorator @pytest.mark.skip(reason="Actual reason")
. When the tests were ported from unitest to pytest, they failed for some reason. When adding new tests to a file, please make an attempt to correct any tests currently skipped in the same file.
- View/Subscribe to the SasView Calendar
- Fortnightly developer's agenda/minutes
- Developer Guides
- Admin Processes and Procedure Notes
- Active Project Pages
- Historical Archive of Obsolete Pages
- Contributor e-Learning Course (free)
- Non Coding contribution needs/projects
- New functionality projects
- DRAFT for acknowledging contributions