Porting from std/unittest
Most test code can be ported from std/unittest with minimal changes, but there are important semantic differences when using certain execution modes.
Quick Porting Checklist
- Replace
import unittestwithimport unittest2. - Keep your existing
suite,test,check, andexpectblocks. - Reduce dependencies on global initialization order.
Execution Order and Discovery
The most significant difference occurs when using Collect-and-Run Mode (-d:unittest2Compat=false). Unlike std/unittest, which executes tests as they are encountered, unittest2 first "discovers" all tests before running any of them.
Code placed directly inside a suite block (but outside of test or setup) will execute during this discovery phase.
import unittest2
# In Collect-and-Run mode (-d:unittest2Compat=false),
# execution is split into Discovery and Execution phases.
suite "execution order":
# This code runs during the Discovery phase.
echo "1. Discovery phase: suite body runs"
setup:
# This runs during the Execution phase, before each test.
echo "3. Execution phase: setup runs before each test"
test "example test":
# This runs during the Execution phase.
echo "4. Execution phase: test body runs"
# This also runs during the Discovery phase.
echo "2. Discovery phase: suite body continues"
To maintain consistent behavior between modes, always place initialization logic inside setup and cleanup logic inside teardown.
Strategy for Large Codebases
- Migrate incrementally: Port one package or module at a time.
- Use Compatibility Mode initially: Keep
-d:unittest2Compat=true(the default) to match the single-pass execution ofstd/unittest. - Switch to Collect-and-Run Mode: Once your tests are independent and free of side effects in the
suitebody, disable compatibility mode to benefit from better reporting and advanced filtering.