Unit testing
Repl unit testing allows a repl author to create code-driven tests that compare actual function output with expected output.
Supported Languages and Testing Frameworks
Why Use Unit Testing?
Unit testing is great for more complicated testing scenarios. For example, when you need to test that functions return specific values based on their (dynamic) inputs.
Each test is itself a function that follows a pattern:
- Invoke one function from your application with parameters.
- Compare the return value to an expected value (your function should always have predictable outputs)
- If the actual value does not match the expected value, the assert method with throw an exception and cause the test to fail.
Here's an example using Java:
// invoke with 3.0, 4.0 as input
double area = calculateRectArea(3.0, 4.0);
// compare expected to actual
assertEqual(12.0, actual);
Unit testing is not ideal for testing that involves using Standard In (System.in
) and Standard Out (System.out
). Input/Output testing is ideal for testing that relies on precise usage of println()
.
Using the Testing Pane
The testing pane can be found in your left-hand sidebar in your repl. It is your hub for creating tests. Read on to find out more about how to use this helpful feature.
Defining a test function
Open the testing pane within a project.
If prompted, select "Unit tests".
Write a function within the main file that's easy to test: something which accepts parameters and returns a single result. Our example includes an add
function which simply returns the result of adding two numbers.
In a Python repl:
In a Node.js repl:
Click "+ Add test".
Providing a test will construct a unit test function for you. Only the body of the function is editable. Configure the test to invoke the add
function and compare the result to the expected value. If the actual value does not match the expected value, the assert method with throw an exception and cause the test to fail. Include a helpful failure message to explain the intent of the test.
Note: Python exposes its assert methods on the self
object. This behavior will be different depending on the language you use. See the "Assertion documentation" below to read about the invocation patterns for each unit testing framework.
In a Python repl:
In a Node.js repl:
Note: by default, in a Node.js repl, the exports are available via an index
variable, e.g. index.add
here. You can add your own imports too, see the "Importing Libraries" section.
Click "Run tests" to begin executing your test suite. Open the Console tab to monitor execution progress.
Test results will appear in the Console.
Importing libraries
Imports can be configured in the "Setup" for the test suite, which is helpful if:
- Your repl has library dependencies.
- You would like to include any other library just for testing purposes.
For example, you can import NumPy for all tests. Keep in mind that this will affect all test functions within your test suite (you will not need to import more than once):
Here is an example function using NumPy:
Every other test you write can also use NumPy:
Importing modules
If you would like to test multiple modules or files within your repl, you must manually import them in the "Setup".
Advanced Setup and Teardown
Sometimes tests require specific setup and teardown steps to configure and destroy global state.
Consider a repl that relies on Repl Database and loads specific data by key.
Import
Use import to include Repl Database.
Setup
Use the setup to add a database key with test data:
Teardown
Use the teardown to delete the test data:
Assertion Documentation
Read about the supported assert function for each unit testing library:
- Java – JUnit
- Python – unittest assert methods
- Node.js – Jest expect functions
Tips for Writing Good Tests
- Only test one expected output at a time.
- Avoid relying on external libraries when possible.
- Avoid testing functions that rely on the entire app running (e.g. databases, network connections, rendering user-interfaces).
- Avoid testing functions that are not crucial portions of the program.
- Avoid testing functions that are part of external libraries.
Tips for Writing "Testable" Functions
- Decompose your program into discrete functions.
- Keep functions concise and descriptive.
- Design predictable inputs (parameters) and outputs (return).
Teams for Education
Unit testing is supported in Teams for Education. If you don't have a team yet, create one here.
Creating a project
If you are new to projects, you can find more info on creating a project here.