I have a python class that has methods to perform the CRUD operations via REST api:
class my_class():
def get_obj(self,...) -> requests.Response:
res = requests.get(...);
return res;
def create_obj(self, ...) -> requests.Response:
res = requests.post(...);
return res;
def modify_obj(self, ...) -> requests.Response:
res = requests.put(...);
return res;
def delete_obj(self, ...) -> requests.Response:
res = requests.delete(...)
return res;
I want to test these functionalities and to do that I can think of 3 ways:
a single test that tests in cascade all the functionalities, something like:
class test_myclass(unittest.TestCase): def setUp(self): self.api_class = my_class(); def test_all(self): res = self.api_class.create_obj(); self.assertTrue(res.ok); res = self.api_class.get_obj(); self.assertTrue(res.ok); res = self.api_class.modify_obj(); self.assertTrue(res.ok); res = self.api_class.modify_obj(); self.assertTrue(res.ok);
This has the advantage of being very compact and when the test succeed, everything is clean: all the created stuff is deleted. On the contrary, if one of the middle tests fails, then problems arise so maybe a
tearDown()
is needed.The second way is to test each functionality with a method:
class test_myclass(unittest.TestCase): def setUp(self): self.api_class = my_class(); def test_create(self): res = self.api_class.create_obj(); if res.ok: self.api_class.delete_obj(); self.assertTrue(res.ok); def test_get(self): res0 = self.api_class.create_obj(); res = self.api_class.get_obj(); if res0.ok: self.api_class.delete_obj(); self.assertTrue(res.ok); def test_modify(): res0 = self.api_class.create_obj(); res = self.api_class.modify_obj(); if res0.ok: self.api_class.delete_obj(); self.assertTrue(res.ok); def test_delete self.api_class.create_obj(); res = self.api_class.delete_obj(); self.assertTrue(res.ok);
This way is much more redundant but in my opinion tests are cleaner if a problem arises.
The third way is to write a test class for each functionality: each one with a
setUp
andtearDown
method:class test_myclass_create(unittest.TestCase): def tearDown(self): self.api_class.delete_obj(); def test_create(self): res = self.api_class.create_obj(); self.assertTrue(res.ok); class test_myclass_get(unittest.TestCase): def tearDown(self): self.api_class.delete_obj(); def setUp(self): self.api_class.create_obj(); def test_get(self): res = self.api_class.get_obj(); self.assertTrue(res.ok); class test_myclass_modify(unittest.TestCase): def tearDown(self): self.api_class.delete_obj(); def setUp(self): self.api_class.create_obj(); def test_modify(): res = self.api_class.modify_obj(); self.assertTrue(res.ok); class test_myclass_get(unittest.TestCase): def tearDown(self): self.api_class.delete_obj(); def setUp(self): self.api_class.create_obj(); def test_delete: res = self.api_class.delete_obj(); self.assertTrue(res.ok);
Does a best practice exist for such a case or is it just up to to the programmer?