<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://teaching.healthtech.dtu.dk:443/22118/index.php?action=history&amp;feed=atom&amp;title=Example_code_-_Unit_test</id>
	<title>Example code - Unit test - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://teaching.healthtech.dtu.dk:443/22118/index.php?action=history&amp;feed=atom&amp;title=Example_code_-_Unit_test"/>
	<link rel="alternate" type="text/html" href="https://teaching.healthtech.dtu.dk:443/22118/index.php?title=Example_code_-_Unit_test&amp;action=history"/>
	<updated>2026-05-18T03:07:02Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://teaching.healthtech.dtu.dk:443/22118/index.php?title=Example_code_-_Unit_test&amp;diff=101&amp;oldid=prev</id>
		<title>WikiSysop: Created page with &quot;I decided to make some unit tests for my prime number generator, I used as an example last week, see Example code - Classes I make two files - one file containing the class &#039;&#039;PrimeGenerator.py&#039;&#039; and one file containing the tests, &#039;&#039;test_PrimeGenerator.py&#039;&#039;. The files are supposed to be in the same folder. I will not show the code from last week in &#039;&#039;PrimeGenerator.py&#039;&#039;, if you want to see the code, click the above link. &lt;p&gt;  This is my unit test file. I want to test...&quot;</title>
		<link rel="alternate" type="text/html" href="https://teaching.healthtech.dtu.dk:443/22118/index.php?title=Example_code_-_Unit_test&amp;diff=101&amp;oldid=prev"/>
		<updated>2026-01-27T08:41:58Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;I decided to make some unit tests for my prime number generator, I used as an example last week, see &lt;a href=&quot;/22118/index.php/Example_code_-_Classes&quot; title=&quot;Example code - Classes&quot;&gt;Example code - Classes&lt;/a&gt; I make two files - one file containing the class &amp;#039;&amp;#039;PrimeGenerator.py&amp;#039;&amp;#039; and one file containing the tests, &amp;#039;&amp;#039;test_PrimeGenerator.py&amp;#039;&amp;#039;. The files are supposed to be in the same folder. I will not show the code from last week in &amp;#039;&amp;#039;PrimeGenerator.py&amp;#039;&amp;#039;, if you want to see the code, click the above link. &amp;lt;p&amp;gt;  This is my unit test file. I want to test...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;I decided to make some unit tests for my prime number generator, I used as an example last week, see [[Example code - Classes]]&lt;br /&gt;
I make two files - one file containing the class &amp;#039;&amp;#039;PrimeGenerator.py&amp;#039;&amp;#039; and one file containing the tests, &amp;#039;&amp;#039;test_PrimeGenerator.py&amp;#039;&amp;#039;. The files are supposed to be in the same folder.&lt;br /&gt;
I will not show the code from last week in &amp;#039;&amp;#039;PrimeGenerator.py&amp;#039;&amp;#039;, if you want to see the code, click the above link.&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is my unit test file. I want to test the following:&lt;br /&gt;
* It can generate different series of primes in a not-ascending order (i.e 10, 20, 15)&lt;br /&gt;
* It can figure out if a number is a prime, especially around 0.&lt;br /&gt;
* It reacts correctly on wrong (nonsense) input&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;File:&amp;#039;&amp;#039;&amp;#039; test_PrimeGenerator.py&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pytest&lt;br /&gt;
from PrimeGenerator import PrimeGenerator&lt;br /&gt;
&lt;br /&gt;
# Parametric test of the generator part&lt;br /&gt;
@pytest.mark.parametrize(&amp;quot;x, y&amp;quot;, [(10,(2,3,5,7)), (20,(2,3,5,7,11,13,17,19)), (15,(2,3,5,7,11,13))])&lt;br /&gt;
&lt;br /&gt;
def test_generator(x, y):&lt;br /&gt;
    result = tuple(PrimeGenerator(x))&lt;br /&gt;
    assert result == y, &amp;quot;Generator test&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
# Parametric test of the giving illegal data to the generator&lt;br /&gt;
@pytest.mark.parametrize(&amp;quot;x&amp;quot;, [1.3, 6.5, &amp;#039;Cat&amp;#039;, [1,2,3,4], {1,2,3,4}, {1:1, 2:2, 3:3, 4:4}])&lt;br /&gt;
&lt;br /&gt;
def test_generator_illegal(x):&lt;br /&gt;
    with pytest.raises(ValueError):&lt;br /&gt;
        PrimeGenerator(x)&lt;br /&gt;
&lt;br /&gt;
# Parametric test of the isprime part&lt;br /&gt;
@pytest.mark.parametrize(&amp;quot;x, y&amp;quot;, [(-3, False),(-2, False),(0, False),(1, False),(2, True),(3, True),(4, False),(5, True),(100, False),(47, True)])&lt;br /&gt;
&lt;br /&gt;
def test_isprime_compute(x, y):&lt;br /&gt;
    assert PrimeGenerator().isprime(x) == y, &amp;quot;isprime test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Parametric test of the giving illegal data to isprime&lt;br /&gt;
@pytest.mark.parametrize(&amp;quot;x&amp;quot;, [1.3, 6.5, &amp;#039;Cat&amp;#039;, [1,2,3,4], {1,2,3,4}, {1:1, 2:2, 3:3, 4:4}])&lt;br /&gt;
&lt;br /&gt;
def test_isprime_illegal(x):&lt;br /&gt;
    with pytest.raises(ValueError):&lt;br /&gt;
        PrimeGenerator().isprime(x)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
When running the unit tests with &amp;#039;&amp;#039;&amp;#039;pytest test_PrimeGenerator.py&amp;#039;&amp;#039;&amp;#039;, I got the following problems.&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_generator_illegal[1.3] - Failed: DID NOT RAISE &amp;lt;class &amp;#039;ValueError&amp;#039;&amp;gt;&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_generator_illegal[6.5] - Failed: DID NOT RAISE &amp;lt;class &amp;#039;ValueError&amp;#039;&amp;gt;&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_generator_illegal[x3] - TypeError: int() argument must be a string, a bytes-like ...&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_generator_illegal[x4] - TypeError: int() argument must be a string, a bytes-like ...&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_generator_illegal[x5] - TypeError: int() argument must be a string, a bytes-like ...&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_isprime_illegal[1.3] - Failed: DID NOT RAISE &amp;lt;class &amp;#039;ValueError&amp;#039;&amp;gt;&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_isprime_illegal[6.5] - Failed: DID NOT RAISE &amp;lt;class &amp;#039;ValueError&amp;#039;&amp;gt;&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_isprime_illegal[Cat] - TypeError: &amp;#039;&amp;lt;=&amp;#039; not supported between instances of &amp;#039;str&amp;#039; a...&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_isprime_illegal[x3] - TypeError: &amp;#039;&amp;lt;=&amp;#039; not supported between instances of &amp;#039;list&amp;#039; a...&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_isprime_illegal[x4] - TypeError: &amp;#039;&amp;lt;=&amp;#039; not supported between instances of &amp;#039;set&amp;#039; an...&lt;br /&gt;
 FAILED test_PrimeGenerator.py::test_isprime_illegal[x5] - TypeError: &amp;#039;&amp;lt;=&amp;#039; not supported between instances of &amp;#039;dict&amp;#039; a...&lt;br /&gt;
Despite my best effort in making the PrimeGenerator class, I overlooked something, not in the core code, but in the validation of input.&lt;br /&gt;
The truth is that I did not think of my test_generator_illegal unit test to begin with, but when I made the test_isprime_illegal and it failed, then I realized the other input validation problem. This just shows that is it valuable to make the unit tests, even with the most stupid and inane test you can think of.&lt;br /&gt;
&lt;br /&gt;
Having fixed my code issues, I here present the new PrimeGenerator code.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python3&lt;br /&gt;
# Prime number generator&lt;br /&gt;
&lt;br /&gt;
class PrimeGenerator:&lt;br /&gt;
    # Class varible, known primes in consecutive order, can be extended, but must contain these&lt;br /&gt;
    knownprimes = [2, 3]&lt;br /&gt;
    # Highest tested number for prime&lt;br /&gt;
    highesttested = 3&lt;br /&gt;
&lt;br /&gt;
    # Instatiation&lt;br /&gt;
    def __init__(self, number=None):&lt;br /&gt;
        if number is not None:&lt;br /&gt;
            if not isinstance(number, int):                # New code&lt;br /&gt;
                raise ValueError(&amp;quot;Integer expected&amp;quot;)       # New code&lt;br /&gt;
        self.target = number                &lt;br /&gt;
    &lt;br /&gt;
    # Initializing iteration&lt;br /&gt;
    def __iter__(self):&lt;br /&gt;
        if self.target is None:&lt;br /&gt;
            raise ValueError(&amp;quot;No number specified&amp;quot;)&lt;br /&gt;
        self.pos = 0&lt;br /&gt;
        return self&lt;br /&gt;
    &lt;br /&gt;
    # Find next prime&lt;br /&gt;
    def __next__(self):&lt;br /&gt;
        # Can we use the list of known primes to find the next?&lt;br /&gt;
        if self.pos &amp;lt; len(self.knownprimes):&lt;br /&gt;
            nextprime = self.knownprimes[self.pos]&lt;br /&gt;
            if nextprime &amp;gt;= self.target:&lt;br /&gt;
                raise StopIteration&lt;br /&gt;
            self.pos += 1&lt;br /&gt;
            return nextprime&lt;br /&gt;
        # No, start computing the next prime&lt;br /&gt;
        while self.target &amp;gt; PrimeGenerator.highesttested+1:&lt;br /&gt;
            PrimeGenerator.highesttested += 1&lt;br /&gt;
            if self._isprime(PrimeGenerator.highesttested):&lt;br /&gt;
                self.knownprimes.append(PrimeGenerator.highesttested)&lt;br /&gt;
                self.pos += 1&lt;br /&gt;
                return self.highesttested&lt;br /&gt;
        raise StopIteration&lt;br /&gt;
&lt;br /&gt;
    # Private method for identifying a prime&lt;br /&gt;
    def _isprime(self, number):&lt;br /&gt;
        factor = 0&lt;br /&gt;
        pos = 0&lt;br /&gt;
        while factor*factor &amp;lt;= number:&lt;br /&gt;
            # find next potential factor either in known primes or odd numbers above last known prime&lt;br /&gt;
            if pos &amp;lt; len(self.knownprimes):&lt;br /&gt;
                factor = self.knownprimes[pos]&lt;br /&gt;
                pos += 1&lt;br /&gt;
            else:&lt;br /&gt;
                factor += 2&lt;br /&gt;
            # test if it truly is a factor&lt;br /&gt;
            if number % factor == 0:&lt;br /&gt;
                return False&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    # It is nice be able to ask if an number is a prime&lt;br /&gt;
    def isprime(self, number=None):&lt;br /&gt;
        if number is None:&lt;br /&gt;
            number = self.target&lt;br /&gt;
        if not isinstance(number, int):                # New code&lt;br /&gt;
            raise ValueError(&amp;quot;Integer expected&amp;quot;)&lt;br /&gt;
        if number in PrimeGenerator.knownprimes:&lt;br /&gt;
            return True&lt;br /&gt;
        if number &amp;lt;= PrimeGenerator.highesttested:&lt;br /&gt;
            return False&lt;br /&gt;
        return self._isprime(number)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    # Small testing&lt;br /&gt;
    for i in PrimeGenerator(1000):&lt;br /&gt;
        print(i)&lt;br /&gt;
&lt;br /&gt;
    print(PrimeGenerator().isprime(1000000016531)) # True&lt;br /&gt;
    print(PrimeGenerator().isprime(1000000016521)) # False&lt;br /&gt;
&lt;br /&gt;
    # Big prime, don&amp;#039;t try&lt;br /&gt;
    # 999296950101072104250052714631&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
</feed>