Quick Start
Welcome! If you are new to Touca, this is the right place to be! Our main objective here is to introduce Touca without taking too much of your time. We hope to make you excited enough to check out our hands-on tutorials next.

# Revisiting Unit Testing

Let us imagine that we want to test a software workflow that reports whether a given number is prime.
Python
C++
TypeScript
Java
1
def is_prime(number: int):
Copied!
1
bool is_prime(const int number);
Copied!
1
function is_prime(number: number): boolean;
Copied!
1
public static boolean isPrime(final int number);
Copied!
We can use unit testing in which we hard-code a set of input numbers and list our expected return value for each input.
Python
C++
TypeScript
Java
1
from code_under_test import is_prime
2
â€‹
3
def test_is_prime():
4
assert is_prime(-1) == False
5
assert is_prime(1) == False
6
assert is_prime(2) == True
7
assert is_prime(13) == True
Copied!
1
#include "catch2/catch.hpp"
2
#include "code_under_test.hpp"
3
â€‹
4
TEST_CASE("is_prime") {
5
CHECK(is_prime(-1) == false);
6
CHECK(is_prime(1) == false);
7
CHECK(is_prime(2) == true);
8
CHECK(is_prime(13) == true);
9
}
Copied!
1
import { is_prime } from "code_under_test";
2
â€‹
3
test("test is_prime", () => {
4
expect(is_prime(-1)).toEqual(false);
5
expect(is_prime(1)).toEqual(false);
6
expect(is_prime(2)).toEqual(true);
7
expect(is_prime(13)).toEqual(true);
8
});
Copied!
1
import org.junit.jupiter.api.Test;
2
import static org.junit.jupiter.api.Assertions.assertFalse;
3
import static org.junit.jupiter.api.Assertions.assertTrue;
4
â€‹
5
public final class PrimeTest {
6
â€‹
7
@Test
8
public void isPrime() {
9
assertFalse(Prime.isPrime(-1));
10
assertFalse(Prime.isPrime(1));
11
assertTrue(Prime.isPrime(2));
12
assertTrue(Prime.isPrime(13));
13
}
14
}
Copied!
Unit testing is an effective method to gain confidence in the behavior of functions we are going to implement or have already implemented. But let us, for a moment, review some of the fundamentals of building and maintaining unit tests:
• For each input, we need to specify the corresponding expected output, as part of our test logic.
• As our software requirements evolve, we may need to go back and change our expected outputs.
• When we find other interesting inputs, we may need to go back and include them in our set of inputs.
In our example, the input and output of our code under test are a number and a boolean. If we were testing a video compression algorithm, they may have been video files. In that case:
• Describing the expected output for a given video file would be difficult.
• When we make changes to our compression algorithm, accurately reflecting those changes in our expected values would be time-consuming.
• We would need a large number of input video files to gain confidence that our algorithm works correctly.

# Introducing Touca

Touca makes it easier to continuously test workflows of any complexity and with any number of test cases.
Python
C++
TypeScript
Java
1
import touca
2
â€‹
3
@touca.Workflow
4
def is_prime_test(testcase: str):
5
touca.check("output", is_prime(int(testcase)))
6
â€‹
7
if __name__ == "__main__":
8
touca.run()
Copied!
1
#include "touca/touca.hpp"
2
#include "code_under_test.hpp"
3
â€‹
4
int main(int argc, char* argv[]) {
5
touca::workflow("is_prime", [](const std::string& testcase) {
6
const auto number = std::stoul(testcase);
7
touca::check("output", is_prime(number));
8
});
9
touca::run(argc, argv);
10
}
Copied!
1
import { touca } from "@touca/node";
2
import { is_prime } from "./code_under_test";
3
â€‹
4
touca.workflow("is_prime_test", (testcase: string) => {
5
touca.check("output", is_prime(Number.parseInt(testcase)));
6
});
7
â€‹
8
touca.run();
Copied!
1
import io.touca.Touca;
2
â€‹
3
public final class PrimeTest {
4
â€‹
5
@Touca.Workflow
6
public void isPrime(final String testcase) {
7
final int number = Integer.parseInt(testcase);
8
Touca.check("output", Prime.isPrime(number));
9
}
10
â€‹
11
public static void main(String[] args) {
12
Touca.run(PrimeTest.class, args);
13
}
14
}
Copied!
This code needs some explanation. Let us start by reviewing what is missing:
• We have fully decoupled our test inputs from our test logic. We refer to these inputs as "test cases". Our open-source SDKs retrieve the test cases from the command line, or a file, or a remote Touca server and feed them one by one to our code under test.
• We have removed the concept of expected values. With Touca, we only describe the actual behavior and performance of our code under test by capturing values of interesting variables and runtime of important functions, from anywhere within our code. Touca SDKs submit this description to a remote Touca server which compares it against the description for a trusted version of our code. The server visualizes any differences and reports them in near real-time.
We can run Touca tests with any number of inputs from the command line:
Python
C++
TypeScript
Java
1
export TOUCA_API_KEY=<TOUCA_API_KEY>
2
export TOUCA_API_URL=<TOUCA_API_URL>
3
python3 prime_app_test.py --revision v1.0 --testcase 13 17 51
Copied!
1
export TOUCA_API_KEY=<TOUCA_API_KEY>
2
export TOUCA_API_URL=<TOUCA_API_URL>
3
./prime_app_test --revision v1.0 --testcase 13,17,51
Copied!
1
export TOUCA_API_KEY=<TOUCA_API_KEY>
2
export TOUCA_API_URL=<TOUCA_API_URL>
3
node dist/is_prime_test.js --revision v1.0 --testcase 13 17 51
Copied!
1
export TOUCA_API_KEY=<TOUCA_API_KEY>
2
export TOUCA_API_URL=<TOUCA_API_URL>
3
gradle runExampleMinimal --args='--revision v1.0 --testcase 13 17 51'
Copied!
Where `TOUCA_API_KEY` and `TOUCA_API_URL` can be obtained from the Touca server at app.touca.io. This command produces the following output:
1
Touca Test Framework
2
Suite: is_prime_test/v1.0
3
â€‹
4
1. PASS 13 (127 ms)
5
2. PASS 17 (123 ms)
6
3. PASS 51 (159 ms)
7
â€‹
8
Tests: 3 passed, 3 total
9
Time: 0.57 s
10
â€‹
11
âœ¨ Ran all test suites.
Copied!
If and when we change the implementation of `is_prime`, we can rerun the test (passing a different version number) and submit the results for the new version to the Touca server. The server takes care of storing and comparing the results submitted between the two versions and reports the differences in near real-time.
The Touca server considers the test results submitted for the first version of our test, as our baseline: all subsequent versions submitted to the server would be compared against it. If, for any reason, requirements of our software change and we decide to change this baseline, we can do so by clicking a button right from the Touca server UI.
Touca Server

# Value Proposition

Touca is very effective in addressing common problems in the following situations:
• When we need to test our workflow with a large number of inputs.
• When the output of our workflow is too complex, or too difficult to describe in our unit tests.
• When interesting information to check for regression is not exposed through the interface of our workflow.
The highlighted design features of Touca can help us test these workflows at any scale.
• Decoupling our test input from our test logic, can help us manage our long list of inputs without modifying the test logic. Managing that list on a remote server accessible to all members of our team, can help us add notes to each test case, explain why they are needed and track how their performance changes over time.
• Submitting our test results to a remote server, instead of storing them in files, can help us avoid the mundane tasks of managing and processing of those results. The Touca server retains test results and makes them accessible to all members of the team. It compares test results using their original data types and reports discovered differences in real-time to all interested members of our team. It allows us to audit how our software evolves over time and provides high-level information about our tests.