---
url: /apranik/contribute/tests.md
description: >-
  How Apranik's tests are written: next to the code, with real bytes, and a
  module's tests never import core.
---

# Tests

* Tests live next to the code, in `_test.go` files, mostly as external test
  packages (`package tcp_test`).
* **A module's tests never import `core/`.** That the contract alone is enough is
  the point of the design.
* Prefer real bytes: the TLS sniffer tests use ClientHellos generated by
  `crypto/tls`; proxy tests run both roles over `net.Pipe`; overlay tests run
  both roles over a loopback TCP pair, which half-closes and has deadlines.
* Generate keys and certificates in the test (`crypto/x509`), so no key material
  is ever committed.
* Parsers of untrusted bytes get a fuzz target (`go test -fuzz`), as the Trojan
  wire format and the WebSocket frame reader have.
* End-to-end tests in `core/builder` build a server and a client from config
  files, as `apranik run` does, and carry TCP and UDP through them.
* Core tests use small fakes of `spec` interfaces (see
  `core/relay/datagram_test.go`) or real UDP sockets on `127.0.0.1`.
* Everything runs under `-race`.
