Testing Techniques
Bioinformatics code is easy to test when you structure it well: pure functions over small inputs, fixtures for sequence data, and unit tests for each parsing/statistics step. This chapter covers the testing patterns that keep a Biopython pipeline trustworthy.
pytest as the Runner
pip install pytest
pytest -v test_seqs.py
# test_seqs.py
from Bio.Seq import Seq
def test_reverse_complement():
assert str(Seq("ATGC").reverse_complement()) == "GCAT"
def test_translate():
prot = Seq("ATGAAATAA").translate()
assert str(prot) == "M*"
Fixtures for Sequence Data
import pytest
from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord
@pytest.fixture
def demo_record():
return SeqRecord(Seq("ATGCGTACGTAA"), id="demo", description="demo seq")
def test_feature_count(demo_record):
demo_record.features.append("CDS")
assert len(demo_record.features) == 1
Temporary Files for I/O Tests
import pytest
from Bio import SeqIO
from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord
def test_fasta_roundtrip(tmp_path):
rec = SeqRecord(Seq("ATGC"), id="r1")
p = tmp_path / "r1.fasta"
SeqIO.write([rec], str(p), "fasta")
loaded = SeqIO.read(str(p), "fasta")
assert str(loaded.seq) == "ATGC"
assert loaded.id == "r1"
pytest's tmp_path gives each test an isolated directory - no pollution, no manual cleanup.
Testing Network Code (Entrez)
- Isolate network calls behind a small fetch function; test the parsing logic on a saved response file (VCR-style cassette or a local fixture).
- Keep a test-only endpoint or mock the HTTP layer; never hit NCBI in unit tests (rate limits + flakiness).
- Test that email/api_key are set before calling Entrez, and that handles are closed.
Property-Style Checks
import random
from Bio.Seq import Seq
def test_rc_is_involution():
random.seed(1)
for _ in range(50):
s = Seq("".join(random.choice("ACGT") for _ in range(12)))
assert str(s.reverse_complement().reverse_complement()) == str(s)
Putting It in CI
# GitHub Actions style
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt pytest
pytest -v
Summary
Test Biopython code with pytest: pure-function unit tests for sequence operations, fixtures for records, tmp_path for I/O round-trips, saved-response fixtures for Entrez (no live network in tests), and property-style checks (like reverse-complement involution). Run the suite in CI so a parser or statistic change is caught before it reaches production pipelines.