Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing in Python

Vmeyet
March 19, 2014

Testing in Python

Vmeyet

March 19, 2014
Tweet

More Decks by Vmeyet

Other Decks in Programming

Transcript

  1. There are actually a lot of different kinds of testing

    Functional Testing Integration Testing Unit Testing Mocking Fixtures Fuzz testing + Source code checking + Code coverage + Continuous integration
  2. Unittest Rule of thumb Focus on one tiny bit of

    functionality and prove it correct Each test unit must be fully independent Tests should be logically as simple as possible Ensure that tests run fast Write tests for parts with fewest dependencies on external resources first, and work your way up Nothing is private: Test every private method unless they correspond to a trivial implementation detail Thumbs Up by Andrew Walsh
  3. Unittest where to put them ? project/ |-tests/ | |-mod_1_test.py

    | |-mod_2_test.py | `-submodule/ | `-sub_test.py | |-lib/ | |-mod_1.py | |-mod_2.py | `-submodule/ | |-__init__.py | `-sub.py `-manage.py project/ |-lib/ | |-mod_1.py | |-mod_1_test.py | |-mod_2.py | |-mod_2_test.py | `-submodule/ | |-__init__.py | |-sub.py | `-sub_test.py `-manage.py project/ |-lib/ | |-mod_1.py | |-mod_2.py | |-tests/ | | |-mod_1_test.py | | `-mod_2_test.py | `-submodule/ | |-__init__.py | |-sub.py | `-tests/ | `-sub_test.py `-manage.py @Work4
  4. #Debug start by writing a test pinpointing the bug Use

    long and descriptive names for testing functions sqrt vs test_001_square_of_negative_number_raise_value_error Use the appropriate assertion assertTrue / assertLess / assertIsInstance / assertDictEqual Order of arguments assertEqual(expected, actual) Mock with parsimony Third-party lib / HTTP call over network (mailer, api) / Randomness / heavy-load non-relevant part of code Test realistic edge cases test_is_prime({"toto": [1, 2, 3]}) vs test_is_prime(0) Unittest Best practices
  5. Unittest Examples class TinderUserTest(TestCase): def setUp(self): self.user = TinderUser.objects.create() def

    tearDown(self): TinderUser.objects.delete() def test_no_match_if_fbach(self): self.user.name = "FBach" actual = self.user.matches self.assertSetEqual(set(), actual) def test_match_if_not_fbach(self): self.user.name = "FBach" actual = self.user.matches unexpected = set() self.assertNotEqual(unexpected, actual) @patch("match.Match.get_uid") def test_search_for_matches(self, mock): actual = self.user._search_for_matches() class TinderUser(models.Model): name = models.StringField() @property def matches(self): if self.name == "FBach": return {"count": 0, "matches": set()} return self._search_for_matches() def _search_for_matches(self): matches = Match.object( location=self.location) count = matches.count() ret_val = {"count": count} # actual FB call uids = [m.get_uid() for m in matches] rand_m (set()) ret_val["matches"] = rand_m return ret_val
  6. Selenium automates browsers Selenium IDE FireFox add-on to record your

    input Selenium WebBrowser FW to drive the browser def test_known_user_not_logged(self): go_to_recruiter_dashboard() enter_whitelisted_email() click_get_started() click_connect_with_FB() facebook_login(switch_standalone=True) see_the_email_verification_banner() access_sjs() see_sjs_onboarding() # go back to the landing page go_to_recruiter_dashboard() see_the_email_verification_banner()
  7. def use_drug_from(self, dealer_name): dealer = self.msg.get_dealer(dealer_name) if dealer: try: self.drug

    = dealer.get_meth() except ValueError: self.drug = dealer.get_coke() else: self.drug = self.go_to_church() self.drug.use() Hot Coverage (sed "s/Co/Be/") try to go through all possible paths Code can be 100% covered yet not fully tested Mock might make miss some cases > use_drug_from("Heisenberg") > use_drug_from("Pablo Escobar") > use_drug_from("GrandMa") > use_drug_from(None) > with patch.object(o, "get_dealer") as mock > mock.return_value = Dealer("Heisenberg")
  8. TDD & BDD Your api is determined by using it

    Minimal amount of application code Tends to result in extensible architectures Instant feedback Safety net
  9. Debug start by writing a test pinpointing the bug Test

    realistic edge cases Don’t merge code that is not tested Test act as a safeguard when refactoring But don’t test too much the underlying implementation else you’ll refactor as much tests as code Keep in Mind