-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_blast_101_search.py
More file actions
62 lines (52 loc) · 3.07 KB
/
Copy pathtest_blast_101_search.py
File metadata and controls
62 lines (52 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import unittest
import blast_101_search as blast
import programme_settings
# Adapted from oficial Python unittest documentation: https://docs.python.org/3/library/unittest.html
# Python testing guide: https://realpython.com/python-testing/
# help from ChatGPT for structure and writing improved outputs.
class BlastCoreTests(unittest.TestCase):
def setUp(self):
# Use a protein sequence with valid residues
query = "ACDEFGHIKLMNPQRSTVWY"
programme_settings.settings["DEFAULT"]["query_sequence"] = query
programme_settings.settings["BLAST"]["word_size"] = "4"
programme_settings.settings["BLAST"]["tscore"] = "10"
programme_settings.settings["BLAST"]["tscore_sim"] = "10"
programme_settings.write() # Persist the settings for the module
# update values used by blast module match settings
blast.qsequence = query.upper()
blast.word_size = int(programme_settings.settings["BLAST"]["word_size"])
blast.query_sequence = blast.tdict.create_word_dict(blast.qsequence)
def test_blast_exact_match(self):
'''BLAST search should find high scores for exact matches.'''
print("\nRunning test: BLAST exact match... ", end="")
target_seq = "ACDEFGHIKLMNPQRSTVWY"
score = blast.process_blast(target_seq)
self.assertGreater(score, 0, "Expected a non-zero score for matching sequence")
print(f"PASSED: Exact match score = {score:.2f}")
def test_blast_no_match(self):
'''BLAST search should find zero score for no matching residues.'''
print("\nRunning test: BLAST no match (invalid residues)... ", end="")
target_seq = "ZZZZZZZZZZZZZZZZZZZZ"
score = blast.process_blast(target_seq)
self.assertEqual(score, 0, "Expected a zero score for non-matching sequence")
print("PASSED: No match yielded score = 0")
def test_sequence_shorter_than_wordsize(self):
'''BLAST should return zero score for input shorter than word size.'''
print("\nRunning test: BLAST with query shorter than word size... ", end="")
target_seq = "PWA" # Less than word_size=3
score = blast.process_blast(target_seq)
self.assertEqual(score, 0, "Expected score = 0 for sequence too short to match")
print("PASSED: Sequence too short returned score = 0")
def test_alignment_off_by_one_bug(self):
'''Test alignment does not suffer from off-by-one errors.'''
print("\nRunning test: BLAST alignment shifted by one residue... ", end="")
query = "ACDEFGHIKLMNPQRSTVWY"
# Same sequence shifted by one character should still yield a lower but non-zero score
target = "CDEFGHIKLMNPQRSTVWYA"
score_original = blast.process_blast(query)
score_shifted = blast.process_blast(target)
self.assertLess(score_shifted, score_original, "Off-by-one shifted sequence should have lower score than identical sequence, but not zero.")
print(f"PASSED: Shifted match score = {score_shifted:.2f} < Exact = {score_original:.2f}")
if __name__ == "__main__":
unittest.main()