Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- How to write a test for the Node.js project
- What is a test?
- Most tests in Node.js core are JavaScript programs that exercise a functionality provided by Node.js and check that it behaves as expected.
- Tests should exit with code on success.
- A test will fail if:
- It exits by setting to a non-zero number.
- This is usually done by having an assertion throw an uncaught Error.
- Occasionally, using may be appropriate.
- It never exits.
- In this case, the test runner will terminate the test because it sets a maximum time limit.
- Add tests when:
- Adding new functionality.
- Fixing regressions and bugs.
- Expanding test coverage.
- Test directory structure
- See directory structure overview for outline of existing test & locations.
- When deciding on whether to expand an existing test file or create a new one, consider going through the files related to the subsystem.
- For example, look for when writing a test for.
- Test structure
- Let's analyze this basic test from the Node.js test suite:
- This test ensures that the can handle UTF-8 characters in the http header.
- Lines 1-3
- The first line enables strict mode.
- All tests should be in strict mode unless the nature of the test requires that the test run without it.
- The second line loads the module.
- The is a helper module that provides useful tools for the tests.
- Some common functionality has been extracted into submodules, which are required separately like the fixtures module here.
- Even if a test uses no functions or other properties exported by, the test should still include the module before any other modules
- This is because the module includes code that will cause a test to fail if the test leaks variables into the global space.
- In situations where a test uses no functions or other properties exported by, include it without assigning it to an identifier:
- A test should start with a comment containing a brief description of what it is designed to test.
- The test checks functionality in the module.
- Most tests use the module to confirm expectations of the test.
- The require statements are sorted in order (digits, upper case, lower case).
- This is the body of the test.
- This test is simple, it just tests that an HTTP server accepts characters in the headers of an incoming request.
- Interesting things to notice:
- If the test doesn't depend on a specific port number, then always use 0 instead of an arbitrary value, as it allows tests to run in parallel safely, as the operating system will assign a random port.
- If the test requires a specific port, for example if the test checks that assigning a specific port works as expected, then it is ok to assign a specific port number.
- The use of to check that some callbacks/listeners are called.
- The HTTP server closes once all the checks have run.
- This way, the test can exit gracefully.
- Remember that for a test to succeed, it must exit with a status code of 0.
- General recommendations
- Avoid timers unless the test is specifically testing timers.
- There are multiple reasons for this.
- Mainly, they are a source of flakiness.
- For a thorough explanation go here
- In the event a test needs a timer, consider using the method.
- It allows setting specific timeouts depending on the platform:
- will create a 4-second timeout on most platforms but a longer timeout on slower platforms.
- Make use of the helpers from the module as much as possible.
- Please refer to the common file documentation for the full details of the helpers.
- One interesting case is
- The use of may avoid the use of extra variables and the corresponding assertions.
- Let's explain this with a real test from the test suite.
- This test could be greatly simplified by using like this:
- The common provides a simple countdown mechanism for tests that require a particular action to be taken after a given number of completed tasks (for instance, shutting down an HTTP server after a specific number of requests).
- The countdown callback will be invoked now.
- Some tests will require running Node.js with specific command line flags set.
- To accomplish this, add a comment in the preamble of the test followed by the flags.
- For example, to allow a test to require some of the modules, add the flag.
- A test that would require could start like this:
- When writing assertions, prefer the strict versions:
- Instead of something like
- For performance considerations, we only use a selected subset of features in JavaScript code in the directory.
- However, when writing tests, for the ease of backporting, it is encouraged to use those features that can be used directly without a flag in all maintained branches
- lists available features in each release, such as:
- and over
- Template literals over string concatenation
- Arrow functions when appropriate
- Naming Test Files
- Test files are named using kebab casing.
- The first component of the name is
- The second is the module or subsystem being tested.
- The third is usually the method or event name being tested.
- Subsequent components of the name add more information about what is being tested.
- For example, a test for the event on the object might be named
- If the test specifically checked that arrow functions worked correctly with the event, then it might be named
- Imported Tests
- Web Platform Tests
- Some of the tests for the WHATWG URL implementation (named) are imported from the Web Platform Tests Project
- These imported tests will be wrapped like this:
- The following tests are copied from WPT.
- Modifications to them should be upstreamed first.
- To improve tests that have been imported this way, please send a PR to the upstream project first.
- When the proposed change is merged in the upstream project, send another PR here to update Node.js accordingly.
- Be sure to update the hash in the URL following
- C++ code can be tested using
- Most features in Node.js can be tested using the methods described previously in this document.
- But there are cases where these might not be enough, for example writing code for Node.js that will only be called when Node.js is embedded.
- Adding a new test
- The unit test should be placed in and be named with the prefix followed by the name of unit being tested.
- For example, the code below would be placed in
- Next add the test to the in the target in node.gyp:
- Note that the only sources that should be included in the target are actual test or helper source files.
- There might be a need to include specific object files that are compiled by the target and this can be done by adding them to the section in the target.
- The test can be executed by running the target:
- Node.js test fixture
- There is a named which can be included by unit tests.
- The fixture takes care of setting up the Node.js environment and tearing it down after the tests have finished.
- It also contains a helper to create arguments to be passed into Node.js.
- It will depend on what is being tested if this is required or not.
- To generate a test coverage report, see the Test Coverage section of the Pull Requests guide.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement