@@ -482,21 +482,70 @@ def test_pytest(mocker):
482482 dangerous_sideffects()
483483```
484484
485- ## Testing Edgecases
485+ ## Extensive Input Testing
486486
487- While writing unit tests, you may be tempted to test edgecases. You may have a
488- critical private function or algorithm, which is not part of the public API (so
489- not a good candidate for External testing) and you are concerned about many
490- edgecases that you want to defend against using tests.
487+ The range of inputs that test cases validate is an important decision.
491488
492- It is perfectly valid to write extensive edgecase testing for private code, but
493- these tests should be kept separate from the unit test suite. Extensive edgecase
494- testing makes tests long, and difficult to read (tests are documentation). They
495- can slow down execution, we want unit tests to run first, fast, and often .
489+ When the need for extensive testing starts to conflict with the readability of
490+ test cases and their usefulness as documentation for users and other developers,
491+ the tests should be re-organized into public-facing (concise, expressive, easily
492+ readable), and technical (complex, extensive) test files .
496493
497- - Place them in separate files from unit tests, to improve readability
498- - [ mark them] ( https://docs.pytest.org/en/stable/how-to/mark.html ) so that they
499- can be run as a separate test suite, after your unit test pass
494+ - To maintain readability:
495+ - tests may need to include fewer inputs
496+ - extensive edgecase testing may be moved into different sections or files
497+ - the code itself may need to be refactored
498+ - Avoid testing invalid input; the range of invalid input is infinite, and is
499+ the programming equivalent of trying to prove a negative.
500+ - Focus on inputs relevant to the code under test, and avoid testing the code in
501+ dependencies. Some integration testing of specific behaviors your code relies
502+ on is justifiable.
503+ - [ Fuzz Tests] ( #fuzz-tests ) are the best place to handle extensive and
504+ exhaustive input testing.
505+
506+ ### In Public Interface Tests
507+
508+ These are the most appropriate place to test certain invalid inputs and
509+ dependencies. Public Interface tests act like a contract with users; each
510+ behavior that is tested is like a promise that users can rely on, and expect
511+ that it will not change without warning (and probably a major version bump). So
512+ any input/output and side-effects included in these tests should be considered
513+ _ officially supported behavior_ and given careful consideration.
514+
515+ ### In project level integration tests
516+
517+ These are a good place to handle more extensive input testing. Integration tests
518+ already tend to be more verbose, with a lot of setup and teardown, and much more
519+ behavior to cover than other kinds of tests. These are the kinds of tests that
520+ should focus on edgecases.
521+
522+ ### In Unit Tests
523+
524+ Unit Tests should focus on the "happy-path" of execution. In most cases one
525+ representative example of the _ expected_ input is sufficient. The test case
526+ should illustrate how the unit is expected to be used.
527+
528+ Invalid input should only be tested when the unit itself includes logic to
529+ handle that invalid input.
530+
531+ for example, this code:
532+
533+ ``` python
534+ def foo (x : int ):
535+ return x + 1
536+ ```
537+
538+ should not test its behavior when passed a string (the type annotation already
539+ covers that).
540+
541+ This code should be tested with a string, to cover the exception path.
542+
543+ ``` python
544+ def bar (x ):
545+ if type (x) is str :
546+ raise RuntimeError (" invalid input" )
547+ return x + 1
548+ ```
500549
501550## Additional Types of Test Suites
502551
0 commit comments