deadunit
A dead-simple nesting unit testing module for node.js and in-browser!.
This repository provides default visual representations for the output of deadunit-core,
as well as a formatter that can be used to easily create custom test visualizations.
'Now with browser output!'
- deadunit's dead-simple API only has two major ways to assert behavior (
ok
and count
) making it easy to learn. - deadunit prints the lines of code of asserts in the test results! So your output makes sense even if you don't spend a lot of time writing test commentary.
- deadunit just uses javascript! It doesn't have an awkward sentence-like api.
- deadunit's
count
method elegantly solves various issues like expecting exceptions and asynchronous asserts - just count
up the number of ok
s! - deadunit follows best practices for modular design rather than creating global variables and functions
- deadunit doesn't provide spies. The use of spies is bad practice as tests should treat the modules they test as black boxes by only testing the public API. The internals of these APIs should be left alone.
- deadunit is simpler to use because it doesn't provide needless sugar (e.g. Tree's always-pass/always-fail asserts)
- deadunit doesn't proscribe synchronization for you - it only expects that you tell it how many
ok
s you expect (with count
) when you have asynchronous assertions. - it prints out exception and any attached data they have
- it'll let you know if your code is hanging (something you don't want, but usually goes unnoticed)
- deadunit supports testing code that uses node fibers
- deadunit's output is easier to visually parse than jasmine, or wizek's tree, and much easier than node-unit
Example
var Unit = require('deadunit')
var test = Unit.test('some test name', function() {
this.count(5)
var obj = someFunctionToTest()
this.ok(obj.x === 5)
this.ok(obj.y === 'y')
this.test('nested test', function() {
this.ok(obj.go() > 4)
})
try {
doSomethingBad()
} catch(e) {
this.ok(true)
}
doSomethingAsynchronous(function(result) {
this.ok(result === 'good')
})
})
test.writeConsole()
test.html()
Install
npm install deadunit
Usage
Unit Tester
node.js
var Unit = require('deadunit')
require.js
require(['node_modules/browserPackage/deadunit.browser.gen.umd'], function(Unit) {
browser global-variable
<script src="/node_modules/deadunit/browserPackage/deadunit.browser.gen.umd.js"></script>
<script>
var Unit = deadunit.browser.gen
</script>
Unit.test([<name>, ]<testFunction>)
- runs a suite of unit tests. Returns an ExtendedUnitTest object.
Unit.error(<handler>)
- see deadunit-core
Unit.format(<unitTest>, <printOnTheFly>, <printLateEvents>, <format>)
- creates custom formatted output for test results according to the passed in <format>
.
<unitTest>
is a UnitTest
(or ExtendedUnitTest
) object<printOnTheFly>
- if true, events will be printed to the console as they come in<printLateEvents>
- (optional - default true) if true, a warning will be printed when events come in after the results have been written.<format>
- an object containing functions that format the various types of results. Each formater function should return a String
.
format.assert(result, testName)
format.exception(exception)
exception
is an exception object (could be any object that was thrown)
format.group(name, totalDuration, totalSynchronousDuration, testCaseSuccesses, testCaseFailures,
assertSuccesses, assertFailures, exceptions, results, exceptionResults, nestingLevel)
name
is the test group nametotalDuration
- the total duration the test took from start to the last test-actiontotalSynchronousDuration
- the time it took for the test function to complete synchronously (ignores all asynchronous parts)testCaseSuccesses
- the number of successful asserts (the ok
method) and groups in this test group. Does not count asserts and test-groups inside subtest groupstestCaseFailures
- the number of failed asserts and groups in this test group. Does not count asserts and test-groups inside subtest groupsassertSuccesses
- the number of successful asserts in this test group and all subgroups.assertFailures
- the number of failed asserts in this test group and all subgroups.exceptions
- the number of exceptions in this test group and all subgroups.results
- an array of already-formatted test results.exceptionResults
- an array of already-formatted exceptions.nestingLevel
is what level of test group this is. The top-level test is at level 0.
format.log(values)
values
is an array of logged values
For documentation on how to write unit tests, see deadunit-core.
ExtendedUnitTest
This object extends UnitTest from deadunit-core. Also has the following methods:
test.writeConsole(<hangingTimeout>)
- writes colorized text output to the console. Returns a future that resolves when the console writing is complete. <hangingTimeout>
(optional - default 100) is the number of milliseconds to wait for the script to exit after the results have been written. If the script hasn't exited in that amount of time, a warning will be written. If zero, no warning happens. This only applies to node.js. See below for screenshots.
test.writeHtml(<domElement>)
- writes test output to the dom element who's reference was passed to writeHtml. Returns a future that resolves when the console writing is complete. See below for screenshots.
test.string(<colorize>)
- returns a future that resolves to a string containing formatted test results. <colorize>
should only be set to true if it will be printed to a command-line console. See below for screenshots.
test.html(<printLateEvents>)
- returns a string containing html-formatted test results. See below for screenshots.
<printLateEvents>
- (optional - default true) if true, a warning will be printed when events come in after the results have been written.
test.results(<printLateEvents>)
- see deadunit-core. When called from deadunit, doesn't print a warning for late events, use the events
method if you need to detect that.
Screenshots
![Simple colorized tests Simple colorized tests](https://github.com/fresheneesz/deadunit/raw/HEAD/screenshots/SimpleTestsColorized.png)
![Full colorized test results Full colorized test results](https://github.com/fresheneesz/deadunit/raw/HEAD/screenshots/FullTestColorized.png)
![Plain Text Output Plain Text Output](https://github.com/fresheneesz/deadunit/raw/HEAD/screenshots/PlainTextScreenshot.png)
![Simple HTML tests Simple HTML tests](https://github.com/fresheneesz/deadunit/raw/HEAD/screenshots/SimpleTestsHtml.png)
Passing tests are closed and failling tests are open by default. Clicking on the bars toggles sections open or closed.
![Full HTML test results Full HTML test results](https://github.com/fresheneesz/deadunit/raw/HEAD/screenshots/FullTestHtml.png)
Note about tests with asynchronous parts
Javascript (and node.js especially) has a lot of asynchronous parts.
Deadunit allows your tests to run asychronously/concurrently, but you have to manage that concurrency.
I recommend that you use either:
On browsers, since there is nothing as nice as node.js Domains, thewindow.onerror
handler is used. The onerror
handler has many limitations, one of which is that it doesn't currently return an exception object with a stacktrace. If you want to see a more detailed stacktrace for these kinds of errors, check your browser's console (ahem, if you have one - I'm looking at you older versions of IE) because deadunit will not be able to capture and display a stacktrace in its normal output. One goal for most any code is to have 0 unhandled asyncronous exceptions.
Environment/Browser Support
- node.js
- Browsers - note, on browsers, the source is not yet displayed in the output
- Chrome 31
- Firefox 26
- IE 10
This needs more testing! Please help by testing and reporting bugs in other browsers or browser versions!
Todo
- Test deadunit on more browsers and browser versions
- change time display so it displays full time (with asynchronous parts) as the primary time
- add the ability to stream test results to a browser
- Once
colors
supports a safe mode (where it doesn't modify the String prototype), use that. Modifying builtins is dangerous. - Ability to use a sourcemap file to correct line/column numbers
- Also see the todos for deadunit-core
How to Contribute!
Anything helps:
- Creating issues (aka tickets/bugs/etc). Please feel free to use issues to report bugs, request features, and discuss changes.
- Updating the documentation: ie this readme file. Be bold! Help create amazing documentation!
- Submitting pull requests.
How to submit pull requests:
- Please create an issue and get my input before spending too much time creating a feature. Work with me to ensure your feature or addition is optimal and fits with the purpose of the project.
- Fork the repository
- clone your forked repo onto your machine and run
npm install
at its root - If you're gonna work on multiple separate things, its best to create a separate branch for each of them
- edit!
- If it's a code change, please add to the unit tests (at test/testDeadunit.js) to verify that your change works
- When you're done, run the unit tests and ensure they all pass
- Commit and push your changes
- Submit a pull request: https://help.github.com/articles/creating-a-pull-request
Change Log
- 2.0.12
- keeping up with deadunit-core
- 2.0.11
- add generated browser package to repo (since npm post install doesn't work correctly)
- 2.0.10
- fixing double-printing of exceptions
- 2.0.9
- attempting to work around an npm bug
- 2.0.4
- 2.0.1
- added a note when a test times out
- added the ability to warn if the script is hanging after
test.writeConsole
prints out the test
- 2.0.0 - Breaking Change
- incorporating changes in deadunit-core 2.0.0
- added
test.results
test.writeConsole
and test.html
only return when the test is done (or times out)test.writeConsole
outputs test results as they happen in addition to outputting the final output- removed
test.toString
test.string
and test.html
now return futures
- 1.0.7
- Pretty printing logs other places objects are printed
- html output
- handling properties on exceptions
License
Released under the MIT license: http://opensource.org/licenses/MIT