Testing

BioLang tests are ordinary scripts. Define named test functions, use the assert condition, message statement, call each test, and execute the file with bl run. A failed assertion exits with a non-zero status, which is suitable for local automation and CI.

Test Basics

# tests/test_sequences.bl
fn test_reverse_complement() {
  let actual = reverse_complement(dna"ATCG")
  assert actual == dna"CGAT", "reverse complement"
}

fn test_gc_content() {
  let actual = gc_content(dna"AATTCCGG")
  assert abs(actual - 0.5) < 0.001, "GC content"
}

fn test_collections() {
  let values = [1, 2, 3, 4]
  assert len(values) == 4, "collection length"
  assert contains(values, 3), "collection membership"
}

test_reverse_complement()
test_gc_content()
test_collections()
println("3 tests passed")

Run the test script

bl check tests/test_sequences.bl
bl run tests/test_sequences.bl

Expected Errors

Use try/catch when failure is the expected result.

fn test_missing_file() {
  let failed = try {
    read_fasta("missing-test-file.fa")
    false
  } catch _ {
    true
  }
  assert failed, "missing FASTA should fail"
}

test_missing_file()

Self-Contained Fixtures

Create small fixtures during the test and remove them afterward. The write_text argument order is path first, content second.

fn test_fasta_fixture() {
  let path = temp_file()
  let fasta = join([
    ">seq1",
    "ATCGATCG",
    ">seq2",
    "GCTAGCTA"
  ], "\n")

  write_text(path, fasta)
  let records = read_fasta(path)
  assert len(records) == 2, "FASTA record count"
  assert records[0].id == "seq1", "first FASTA identifier"
  remove(path)
}

test_fasta_fixture()

Property Checks

prop_test repeatedly calls a generator and passes each generated value to a predicate. It returns a result record that can be asserted.

fn generate_length(_iteration) {
  gen_int(1, 100)
}

fn length_is_positive(value) {
  value > 0
}

let result = prop_test(length_is_positive, generate_length, 100)
assert result.passed, "generated lengths must be positive"

CI

Run each test script as a normal command. The shell stops when a script returns a non-zero exit code.

bl check tests/test_sequences.bl tests/test_io.bl
bl run tests/test_sequences.bl
bl run tests/test_io.bl