HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

First time writing test case

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
casewritingtimefirsttest

Problem

I have a list of input, a greedy method and a dynamic programming method. I wrote a unittest script to test my two methods with input list but I don't know if I'm writing it right:

import unittest
from land_selling import Offer, Seller

class LandSellingTest(unittest.TestCase):
    offers1 = [
        Offer(0, 6, 2),
        Offer(1, 2, 4),
        Offer(3, 5, 1),
        Offer(5, 9, 3),
        Offer(7, 10, 2),
        Offer(10, 20, 5),
        Offer(34, 2, 1)
    ]
    offers2 = [
        Offer(6, 10, 4),
        Offer(1, 5, 2),
        Offer(7, 20, 3),
        Offer(2, 7, 1),
        Offer(14, 30, 2),
        Offer(3, 6, 3),
        Offer(8, 15, 2),
        Offer(20, 35, 5),
        Offer(25, 5, 3)
    ]
    offers3 = [
        Offer(17, 1, 12),
        Offer(7, 2, 10),
        Offer(17, 2, 8),
        Offer(20, 3, 6),
        Offer(3, 11, 4),
        Offer(22, 12, 2)
    ]

    // input list
    global offers_list
    offers_list = [offers1, offers2, offers3]

    // greedy output list
    global greedy_answers
    greedy_answers = [4, 3, 2]

    // dynamic output list
    global dynamic_answers
    dynamic_answers = [13, 12, 16]

    @classmethod
    def setUpClass(self):
        self.offers_list = offers_list
        self.greedy_answers = greedy_answers
        self.dynamic_answers = dynamic_answers

    def test_greedy(self):
        for offers, ans in zip(self.offers_list, self.greedy_answers):
            seller = Seller(offers)
            seller.set_up()
            self.assertEqual(len(seller.accepted_offers()), ans)

    def test_dynamic(self):
        for offers, ans in zip(self.offers_list,self.dynamic_answers):
            seller = Seller(offers)
            seller.sort_offers_by_finish()
            self.assertEqual(seller.maximum_profit(), ans)

if __name__ == '__main__':
    unittest.main()

Solution

Using py.test with scenarios

Instead of using unittest, I prefer using pytest. There are few reasons:

  • no need for using test classes



  • test cases are easy to write as very simple functions



  • any inputs to test can be parametrized and easily fed by fixtures or parametrization



  • very easy to have one test case run for one combinations of parameters - makes easier to identify


how large is the share of failing cases.

Here is my rewrite to pytest (all put in one file test_it.py:

Imports:

import pytest
from land_selling import Offer, Seller


Function generating scenarios:

def gen_scenarios(mode):
    assert mode in ["greedy", "dynamic"]

    offers1 = [
        Offer(0, 6, 2),
        Offer(1, 2, 4),
        Offer(3, 5, 1),
        Offer(5, 9, 3),
        Offer(7, 10, 2),
        Offer(10, 20, 5),
        Offer(34, 2, 1)
    ]
    offers2 = [
        Offer(6, 10, 4),
        Offer(1, 5, 2),
        Offer(7, 20, 3),
        Offer(2, 7, 1),
        Offer(14, 30, 2),
        Offer(3, 6, 3),
        Offer(8, 15, 2),
        Offer(20, 35, 5),
        Offer(25, 5, 3)
    ]
    offers3 = [
        Offer(17, 1, 12),
        Offer(7, 2, 10),
        Offer(17, 2, 8),
        Offer(20, 3, 6),
        Offer(3, 11, 4),
        Offer(22, 12, 2)
    ]

    # input list
    offers_list = [offers1, offers2, offers3]

    if mode == "greedy":
        greedy_answers = [4, 3, 2]
        return zip(offers_list, greedy_answers)
    elif mode == "dynamic":
        dynamic_answers = [13, 12, 16]
        return zip(offers_list, dynamic_answers)


Parametrized tests:

@pytest.mark.parametrize("scenario", gen_scenarios("greedy"))
def test_greedy(scenario):
    offers, ans = scenario
    seller = Seller(offers)
    seller.set_up()
    assert len(seller.accepted_offers()) == ans

@pytest.mark.parametrize("scenario", gen_scenarios("dynamic"))
def test_dynamic(scenario):
    offers, ans = scenario
    seller = Seller(offers)
    seller.sort_offers_by_finish()
    assert seller.maximum_profit() == ans


Run it by:

$ py.test -sv test_it.py


I cannot provide sample output as I do not have access to the imported code, but there you will see
another beauty of py.test - really well readable test output.

Code Snippets

import pytest
from land_selling import Offer, Seller
def gen_scenarios(mode):
    assert mode in ["greedy", "dynamic"]

    offers1 = [
        Offer(0, 6, 2),
        Offer(1, 2, 4),
        Offer(3, 5, 1),
        Offer(5, 9, 3),
        Offer(7, 10, 2),
        Offer(10, 20, 5),
        Offer(34, 2, 1)
    ]
    offers2 = [
        Offer(6, 10, 4),
        Offer(1, 5, 2),
        Offer(7, 20, 3),
        Offer(2, 7, 1),
        Offer(14, 30, 2),
        Offer(3, 6, 3),
        Offer(8, 15, 2),
        Offer(20, 35, 5),
        Offer(25, 5, 3)
    ]
    offers3 = [
        Offer(17, 1, 12),
        Offer(7, 2, 10),
        Offer(17, 2, 8),
        Offer(20, 3, 6),
        Offer(3, 11, 4),
        Offer(22, 12, 2)
    ]

    # input list
    offers_list = [offers1, offers2, offers3]

    if mode == "greedy":
        greedy_answers = [4, 3, 2]
        return zip(offers_list, greedy_answers)
    elif mode == "dynamic":
        dynamic_answers = [13, 12, 16]
        return zip(offers_list, dynamic_answers)
@pytest.mark.parametrize("scenario", gen_scenarios("greedy"))
def test_greedy(scenario):
    offers, ans = scenario
    seller = Seller(offers)
    seller.set_up()
    assert len(seller.accepted_offers()) == ans


@pytest.mark.parametrize("scenario", gen_scenarios("dynamic"))
def test_dynamic(scenario):
    offers, ans = scenario
    seller = Seller(offers)
    seller.sort_offers_by_finish()
    assert seller.maximum_profit() == ans
$ py.test -sv test_it.py

Context

StackExchange Code Review Q#125863, answer score: 3

Revisions (0)

No revisions yet.