Skillversitas

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.