4

In some Django Tests I have loop to test many things. in the end-result it shows up as:

Ran 1 test in 3.456s

I would like to increment that counter for each loop, how can I do that? It is using subTest() , but that does not update the counter (which I believe is a parameter testsRun)

my test looks something like this

class MyTestCase(TestCase):

   def test_auth_pages(self):
      pages = ['homepage', 'dashboard', 'profile']

      for page in pages:
         with self.subTest():
            # ....testsRun  += 1 
            self.c.login(username='test', password='test')
            response = self.c.get(reverse_lazy(page))
            self.assertEqual(200, response.status_code, msg=page)
            self.c.logout()
            response = self.c.get(reverse_lazy(page))
            self.assertEqual(302, response.status_code, msg=page) 
Alex
  • 5,759
  • 1
  • 32
  • 47
  • Possible duplicate of [How do you generate dynamic (parameterized) unit tests in python?](https://stackoverflow.com/questions/32899/how-do-you-generate-dynamic-parameterized-unit-tests-in-python) – Brown Bear Jun 03 '19 at 14:49
  • @BearBrown no, it is working fine and it is using `self.subTest()` aleady. I just want to increment the counter. – Alex Jun 03 '19 at 14:56
  • by the answer you should get `Ran 3 tests in 0.006s` i will test it on my local machine or may be i not understand you – Brown Bear Jun 03 '19 at 15:00
  • 1
    Why not just write three tests? If you need to run a large number of test you could always just write a script that writes your tests.py for you. – Red Cricket Jun 09 '19 at 01:34
  • @RedCricket I simplified the code a bit, and it is actually about 40 and will be more later on. A script that generates code can be hard to maintain, since it needs to re-generate after every change. – Alex Jun 09 '19 at 13:45
  • it doesn't matter how many test are run, `test coverage` is important – katoozi Jun 10 '19 at 06:38
  • 1
    Surely you can set the test counter to whatever you want to, e.g. `self._outcome.result.testsRun += len(pages)` (you can even introduce your own context manager `countedSubTest` or whatever for that matter), but why? Subtests are no separate tests entities and are not treated as such anywhere; it's just a tool not to stop the test on failure. – hoefling Jun 11 '19 at 16:47

2 Answers2

1

If you don't mind changing testing framework, consider pytest with pytest-django package. You can easily parametrize a test using @pytest.mark.parametrize:

import pytest

@pytest.mark.parametrize("page_name", ['homepage', 'dashboard', 'profile'])
def test_some_page(page_name, client):
    client.login(username='test', password='test')
    response = client.get(reverse_lazy(page))
    assert response.status_code == 200
    client.logout()
    response = client.get(reverse_lazy(page))
    assert response.status_code == 302

If not, you could create a test function factory that would accept the page name and return a test function for that page:

class MyTestCase(TestCase):

   def _create_page_test(page_name):
       def test_function(self):
           self.c.login(username='test', password='test')
           response = self.c.get(reverse_lazy(page_name))
           self.assertEqual(200, response.status_code, msg=page_name)
           self.c.logout()
           response = self.c.get(reverse_lazy(page_name))
           self.assertEqual(302, response.status_code, msg=page_name)
        return test_function

    test_homepage = _create_page_test("homepage")
    test_dashboard = _create_page_test("dashboard")
    test_profile = _create_page_test("profile")

The added benefit of such changes is that each page has a separate test, independent from the other. That makes debugging easier.

Maciej Gol
  • 15,394
  • 4
  • 33
  • 51
0

You can achieve this with a different test suite.

Check out test generators from the django-nose package

def test_evens():
    for i in range(0, 5):
        yield check_even, i, i*3   # this generates 5 different tests

def check_even(n, nn):
    assert n % 2 == 0 or nn % 2 == 0
diogo.silva
  • 448
  • 4
  • 13