Difference between revisions of "How To Write Unit Tests For OpenSSL"
Line 5: | Line 5: | ||
Rationale per Matt Caswell: We should think about process here. If you are going off to recruit an army of people writing tests then I wonder if it is worth setting up a separate github repository whilst you are building up the tests. We can then merge in from that on a periodic basis. I wouldn't want availability of openssl team committers to be a bottle neck. | Rationale per Matt Caswell: We should think about process here. If you are going off to recruit an army of people writing tests then I wonder if it is worth setting up a separate github repository whilst you are building up the tests. We can then merge in from that on a periodic basis. I wouldn't want availability of openssl team committers to be a bottle neck. | ||
− | |||
− | |||
− | |||
== Use the Test Template Generator == | == Use the Test Template Generator == | ||
Line 26: | Line 23: | ||
#endif /* OPENSSL_NO_WINDOWS */ | #endif /* OPENSSL_NO_WINDOWS */ | ||
+ | </pre> | ||
+ | |||
+ | == Follow Pseudo-xUnit Style == | ||
+ | [http://mike-bland.com/2014/06/05/pseudo-xunit-pattern.html The Pseudo-xUnit Pattern] is that established by [http://git.openssl.org/gitweb/?p=openssl.git;a=blob;f=ssl/heartbeat_test.c ssl/heartbeat_test.c]. This pattern organizes code in a fashion reminiscent of the [http://en.wikipedia.org/wiki/XUnit xUnit] family of unit testing frameworks, without actually using a testing framework. This should lower the barrier to entry for people wanting to write unit tests, but enable a relatively easy migration to an xUnit-based framework if we decide to do so one day. | ||
+ | |||
+ | == Add Makefile Targets == | ||
+ | The following instructions use the <code>Makefile</code> targets for <code>ssl/heartbeat_test.c</code> as an example. | ||
+ | |||
+ | In the <code>Makefile</code> for the library containing the test, add the test source file to the <code>TEST</code> variable: | ||
+ | |||
+ | <pre> | ||
+ | # ssl/Makefile | ||
+ | TEST=ssltest.c heartbeat_test.c | ||
+ | </pre> | ||
+ | |||
+ | In <code>test/Makefile</code>: | ||
+ | * add a variable for the test target near the top of the file, right after the existing test variables | ||
+ | * use the variable to add an executable target to the <code>EXE</code> variable | ||
+ | * use the variable to add an object file target to the <code>OBJ</code> variable | ||
+ | * use the variable to add a source file target to the <code>SRC</code> variable | ||
+ | * add the test target to the <code>alltests</code> target | ||
+ | * add the target to execute the test | ||
+ | * add the target to build the test executable | ||
+ | <pre> | ||
+ | # test/Makefile | ||
+ | HEARTBEATTEST= heartbeat_test | ||
+ | EXE= ... $(HEARTBEATTEST)$(EXE_EXT) | ||
+ | OBJ= ... $(HEARTBEATTEST).o | ||
+ | SRC= ... $(HEARTBEATTEST).c | ||
+ | alltests: \ | ||
+ | ... test_heartbeat | ||
+ | |||
+ | test_heartbeat: $(HEARTBEATTEST)$(EXE_EXT) | ||
+ | ../util/shlib_wrap.sh ./$(HEARTBEATTEST) | ||
+ | |||
+ | $(HEARTBEATTEST)$(EXE_EXT): $(HEARTBEATTEST).o $(DLIBCRYPTO) | ||
+ | @target=$(HEARTBEATTEST); $(BUILD_CMD) | ||
</pre> | </pre> |
Revision as of 15:07, 6 June 2014
This is an outline of the basic process and principles to follow when writing unit tests. This document will evolve quite a bit as the community gains experience.
Forking the Repo
For now, people contributing new unit tests for uncovered code (as opposed to submitting tests with new code changes) should fork Mike Bland's GitHub repository and issue GitHub pull requests. Remember to do all development on a topic branch (not master
). Tests committed to this repo will occasionally get merged into the master OpenSSL repo.
Rationale per Matt Caswell: We should think about process here. If you are going off to recruit an army of people writing tests then I wonder if it is worth setting up a separate github repository whilst you are building up the tests. We can then merge in from that on a periodic basis. I wouldn't want availability of openssl team committers to be a bottle neck.
Use the Test Template Generator
TODO(mbland): Get template generator checked-in. Maybe have a template generator for each library, e.g. ssl/new-test.sh
that has additional setup boilerplate specific to the ssl
library.
Use the test/new-test.sh
script to generate a skeleton test file.
Until we solve the private-symbol problem on Windows, we will need to wrap our unit test code in the following #ifdef
block:
#if !defined(OPENSSL_SYS_WINDOWS) /* All the test code, including main() */ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } #endif /* OPENSSL_NO_WINDOWS */
Follow Pseudo-xUnit Style
The Pseudo-xUnit Pattern is that established by ssl/heartbeat_test.c. This pattern organizes code in a fashion reminiscent of the xUnit family of unit testing frameworks, without actually using a testing framework. This should lower the barrier to entry for people wanting to write unit tests, but enable a relatively easy migration to an xUnit-based framework if we decide to do so one day.
Add Makefile Targets
The following instructions use the Makefile
targets for ssl/heartbeat_test.c
as an example.
In the Makefile
for the library containing the test, add the test source file to the TEST
variable:
# ssl/Makefile TEST=ssltest.c heartbeat_test.c
In test/Makefile
:
- add a variable for the test target near the top of the file, right after the existing test variables
- use the variable to add an executable target to the
EXE
variable - use the variable to add an object file target to the
OBJ
variable - use the variable to add a source file target to the
SRC
variable - add the test target to the
alltests
target - add the target to execute the test
- add the target to build the test executable
# test/Makefile HEARTBEATTEST= heartbeat_test EXE= ... $(HEARTBEATTEST)$(EXE_EXT) OBJ= ... $(HEARTBEATTEST).o SRC= ... $(HEARTBEATTEST).c alltests: \ ... test_heartbeat test_heartbeat: $(HEARTBEATTEST)$(EXE_EXT) ../util/shlib_wrap.sh ./$(HEARTBEATTEST) $(HEARTBEATTEST)$(EXE_EXT): $(HEARTBEATTEST).o $(DLIBCRYPTO) @target=$(HEARTBEATTEST); $(BUILD_CMD)