From b1b92284f496800a4dfd2cea72cb9be07ba8661c Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Fri, 13 Sep 2013 16:52:14 -0400 Subject: First cut at import of quick tutorial. --- docs/quick_tutorial/unit_testing.rst | 117 +++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 docs/quick_tutorial/unit_testing.rst (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst new file mode 100644 index 000000000..cc9dfcc8a --- /dev/null +++ b/docs/quick_tutorial/unit_testing.rst @@ -0,0 +1,117 @@ +=========================== +05: Unit Tests and ``nose`` +=========================== + +Provide unit testing for our project's Python code. + +Background +========== + +As the mantra says, "Untested code is broken code." The Python +community has had a long culture of writing test scripts which ensure +that your code works correctly as you write it and maintain it in the +future. Pyramid has always had a deep commitment to testing, +with 100% test coverage from the earliest pre-releases. + +Python includes a +:ref:`unit testing framework ` in its +standard library. Over the years a number of Python projects, such as +`nose `_, have extended this +framework with alternative test runners that provide more convenience +and functionality. The Pyramid developers use ``nose``, which we'll thus +use in this tutorial. + +Don't worry, this tutorial won't be pedantic about "test-driven +development" (TDD.) We'll do just enough to ensure that, in each step, +we haven't majorly broken the code. As you're writing your code you +might find this more convenient than changing to your browser +constantly and clicking reload. + +We'll also leave discussion of +`coverage `_ for another section. + +Objectives +========== + +- Write unit tests that ensure the quality of our code + +- Install a Python package (``nose``) which helps in our testing + +Steps +===== + +#. First we copy the results of the previous step, as well as install + the ``nose`` package: + + .. code-block:: bash + + (env27)$ cd ..; cp -r debugtoolbar unit_testing; cd unit_testing + (env27)$ python setup.py develop + (env27)$ easy_install nose + +#. Now we write a simple unit test in ``unit_testing/tutorial/tests.py``: + + .. literalinclude:: unit_testing/tutorial/tests.py + :linenos: + +#. Now run the tests: + + .. code-block:: bash + + + (env27)$ nosetests tutorial + . + ---------------------------------------------------------------------- + Ran 1 test in 0.141s + + OK + +Analysis +======== + +Our ``tests.py`` imports the Python standard unit testing framework. To +make writing Pyramid-oriented tests more convenient, Pyramid supplies +some ``pyramid.testing`` helpers which we use in the test setup and +teardown. Our one test imports the view, makes a dummy request, and sees +if the view returns what we expected. + +The ``tests.HelloWorldViewTests.test_hello_world`` test is a small +example of a unit test. First, we import the view inside each test. Why +not import at the top, like in normal Python code? Because imports can +cause effects that break a test. We'd like our tests to be in *units*, +hence the name *unit* testing. Each test should isolate itself to the +correct degree. + +Our test then makes a fake incoming web request, then calls our Pyramid +view. We test the HTTP status code on the response to make sure it +matches our expectations. + +Note that our use of ``pyramid.testing.setUp()`` and +``pyramid.testing.tearDown()`` aren't actually necessary here; they are only +necessary when your test needs to make use of the ``config`` object (it's a +Configurator) to add stuff to the configuration state before calling the view. + +Extra Credit +============ + +#. Change the test to assert that the response status code should be + ``404`` (meaning, not found.) Run ``nosetests`` again. Read the + error report and see if you can decipher what it is telling you. + +#. As a more realistic example, put the ``tests.py`` back as you found + it and put an error in your view, such as a reference to a + non-existing variable. Run the tests and see how this is more + convenient than reloading your browser and going back to your code. + +#. Finally, for the most realistic test, read about Pyramid ``Response`` + objects and see how to change the response code. Run the tests and + see how testing confirms the "contract" that your code claims to + support. + +#. How could we add a unit test assertion to test the HTML value of the + response body? + +#. Why do we import the ``hello_world`` view function *inside* the + ``test_hello_world`` method instead of at the top of the module? + +.. seealso:: See Also: :ref:`pyramid:testing_chapter` -- cgit v1.2.3 From 4042c772c8043ac96a22db439a736fec9ea2aafa Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Fri, 13 Sep 2013 17:09:35 -0400 Subject: All the references re-wired. --- docs/quick_tutorial/unit_testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index cc9dfcc8a..566e09252 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -114,4 +114,4 @@ Extra Credit #. Why do we import the ``hello_world`` view function *inside* the ``test_hello_world`` method instead of at the top of the module? -.. seealso:: See Also: :ref:`pyramid:testing_chapter` +.. seealso:: See Also: :ref:`testing_chapter` -- cgit v1.2.3 From 0a784868bdbc3a0eb226ed00e8d89cda9d181ec5 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Fri, 13 Sep 2013 17:11:42 -0400 Subject: Fix naming of virtualenv prefix. --- docs/quick_tutorial/unit_testing.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index 566e09252..e87c5af62 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -45,9 +45,9 @@ Steps .. code-block:: bash - (env27)$ cd ..; cp -r debugtoolbar unit_testing; cd unit_testing - (env27)$ python setup.py develop - (env27)$ easy_install nose + (env)$ cd ..; cp -r debugtoolbar unit_testing; cd unit_testing + (env)$ python setup.py develop + (env)$ easy_install nose #. Now we write a simple unit test in ``unit_testing/tutorial/tests.py``: @@ -59,7 +59,7 @@ Steps .. code-block:: bash - (env27)$ nosetests tutorial + (env)$ nosetests tutorial . ---------------------------------------------------------------------- Ran 1 test in 0.141s -- cgit v1.2.3 From b0b28ede912c817a62a84b97c332e39eda02d166 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 16 Sep 2013 02:14:53 +0200 Subject: s/env/venv just for sake of consistency --- docs/quick_tutorial/unit_testing.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index e87c5af62..de30ea436 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -45,9 +45,9 @@ Steps .. code-block:: bash - (env)$ cd ..; cp -r debugtoolbar unit_testing; cd unit_testing - (env)$ python setup.py develop - (env)$ easy_install nose + (venv)$ cd ..; cp -r debugtoolbar unit_testing; cd unit_testing + (venv)$ python setup.py develop + (venv)$ easy_install nose #. Now we write a simple unit test in ``unit_testing/tutorial/tests.py``: @@ -59,7 +59,7 @@ Steps .. code-block:: bash - (env)$ nosetests tutorial + (venv)$ nosetests tutorial . ---------------------------------------------------------------------- Ran 1 test in 0.141s -- cgit v1.2.3 From 187104fd81418beeb51592913041d9751bafe08d Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Wed, 25 Sep 2013 09:27:43 -0400 Subject: Quick Tutorial: Improve the setup instructions (adapted from Steve Piercy's work), particularly for Windows. Change all the steps to use $VENV/bin prefixes on commands (don't presume that they have done source env/bin/activate). --- docs/quick_tutorial/unit_testing.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index de30ea436..a71ad0097 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -45,9 +45,9 @@ Steps .. code-block:: bash - (venv)$ cd ..; cp -r debugtoolbar unit_testing; cd unit_testing - (venv)$ python setup.py develop - (venv)$ easy_install nose + $ cd ..; cp -r debugtoolbar unit_testing; cd unit_testing + $ $VENV/bin/python setup.py develop + $ $VENV/bin/easy_install nose #. Now we write a simple unit test in ``unit_testing/tutorial/tests.py``: @@ -59,7 +59,7 @@ Steps .. code-block:: bash - (venv)$ nosetests tutorial + $ $VENV/bin/nosetests tutorial . ---------------------------------------------------------------------- Ran 1 test in 0.141s -- cgit v1.2.3 From b731b5fca253d9d95b3307490aa585e194676c01 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Thu, 26 Sep 2013 17:41:44 -0400 Subject: Quick Tour: shorten the setup part and point to Quick Tutorial Requirements for more explanation. Cross link each Quick Tour section with its Quick Tutorial match. --- docs/quick_tutorial/unit_testing.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index a71ad0097..73b33c588 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -1,3 +1,5 @@ +.. _qtut_unit_testing: + =========================== 05: Unit Tests and ``nose`` =========================== -- cgit v1.2.3 From a2b15855bee4893524609a941954c823bfbcec0d Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Tue, 8 Oct 2013 14:33:16 -0400 Subject: Small quick tutorial fixes post conference. --- docs/quick_tutorial/unit_testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index 73b33c588..ed33f62d7 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -77,7 +77,7 @@ some ``pyramid.testing`` helpers which we use in the test setup and teardown. Our one test imports the view, makes a dummy request, and sees if the view returns what we expected. -The ``tests.HelloWorldViewTests.test_hello_world`` test is a small +The ``tests.TutorialViewTests.test_hello_world`` test is a small example of a unit test. First, we import the view inside each test. Why not import at the top, like in normal Python code? Because imports can cause effects that break a test. We'd like our tests to be in *units*, -- cgit v1.2.3 From 2033eeb3602f330930585678aac926749b9c22f7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 10 Feb 2014 03:22:33 -0600 Subject: - Garden PR #1121 --- docs/quick_tutorial/unit_testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index ed33f62d7..f8a33b39d 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -116,4 +116,4 @@ Extra Credit #. Why do we import the ``hello_world`` view function *inside* the ``test_hello_world`` method instead of at the top of the module? -.. seealso:: See Also: :ref:`testing_chapter` +.. seealso:: See also :ref:`testing_chapter` -- cgit v1.2.3 From f818fabb72f0aa53beb2b559b079dcc038530442 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 20 May 2015 03:23:12 -0700 Subject: punctuation fix --- docs/quick_tutorial/unit_testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index f8a33b39d..4cb7ef714 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -24,7 +24,7 @@ and functionality. The Pyramid developers use ``nose``, which we'll thus use in this tutorial. Don't worry, this tutorial won't be pedantic about "test-driven -development" (TDD.) We'll do just enough to ensure that, in each step, +development" (TDD). We'll do just enough to ensure that, in each step, we haven't majorly broken the code. As you're writing your code you might find this more convenient than changing to your browser constantly and clicking reload. -- cgit v1.2.3 From d68cbc6f69446317bc8b01062609c4779624cfc5 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 7 Apr 2016 03:15:45 -0700 Subject: - update unit_testing.rst --- docs/quick_tutorial/unit_testing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index 4cb7ef714..58512d1cc 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -48,8 +48,8 @@ Steps .. code-block:: bash $ cd ..; cp -r debugtoolbar unit_testing; cd unit_testing - $ $VENV/bin/python setup.py develop - $ $VENV/bin/easy_install nose + $ $VENV/bin/pip install -e . + $ $VENV/bin/pip install nose #. Now we write a simple unit test in ``unit_testing/tutorial/tests.py``: -- cgit v1.2.3 From 86e187a734728611bc8bfd5792133502ffd59160 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 16 Apr 2016 04:44:55 -0700 Subject: quick_tutorial cleanup - replace nose with pytest - cleanup unit_testing.rst --- docs/quick_tutorial/unit_testing.rst | 114 +++++++++++++++++------------------ 1 file changed, 56 insertions(+), 58 deletions(-) (limited to 'docs/quick_tutorial/unit_testing.rst') diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index 58512d1cc..56fd2b297 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -1,55 +1,56 @@ .. _qtut_unit_testing: -=========================== -05: Unit Tests and ``nose`` -=========================== +============================= +05: Unit Tests and ``pytest`` +============================= Provide unit testing for our project's Python code. + Background ========== -As the mantra says, "Untested code is broken code." The Python -community has had a long culture of writing test scripts which ensure -that your code works correctly as you write it and maintain it in the -future. Pyramid has always had a deep commitment to testing, -with 100% test coverage from the earliest pre-releases. - -Python includes a -:ref:`unit testing framework ` in its -standard library. Over the years a number of Python projects, such as -`nose `_, have extended this -framework with alternative test runners that provide more convenience -and functionality. The Pyramid developers use ``nose``, which we'll thus -use in this tutorial. - -Don't worry, this tutorial won't be pedantic about "test-driven -development" (TDD). We'll do just enough to ensure that, in each step, -we haven't majorly broken the code. As you're writing your code you -might find this more convenient than changing to your browser -constantly and clicking reload. - -We'll also leave discussion of -`coverage `_ for another section. +As the mantra says, "Untested code is broken code." The Python community has +had a long culture of writing test scripts which ensure that your code works +correctly as you write it and maintain it in the future. Pyramid has always had +a deep commitment to testing, with 100% test coverage from the earliest +pre-releases. + +Python includes a :ref:`unit testing framework +` in its standard library. Over the years a +number of Python projects, such as :ref:`pytest `, have +extended this framework with alternative test runners that provide more +convenience and functionality. The Pyramid developers use ``pytest``, which +we'll use in this tutorial. + +Don't worry, this tutorial won't be pedantic about "test-driven development" +(TDD). We'll do just enough to ensure that, in each step, we haven't majorly +broken the code. As you're writing your code, you might find this more +convenient than changing to your browser constantly and clicking reload. + +We'll also leave discussion of `pytest-cov +`_ for another section. + Objectives ========== -- Write unit tests that ensure the quality of our code +- Write unit tests that ensure the quality of our code. + +- Install a Python package (``pytest``) which helps in our testing. -- Install a Python package (``nose``) which helps in our testing Steps ===== -#. First we copy the results of the previous step, as well as install - the ``nose`` package: +#. First we copy the results of the previous step, as well as install the + ``pytest`` package: .. code-block:: bash $ cd ..; cp -r debugtoolbar unit_testing; cd unit_testing $ $VENV/bin/pip install -e . - $ $VENV/bin/pip install nose + $ $VENV/bin/pip install pytest #. Now we write a simple unit test in ``unit_testing/tutorial/tests.py``: @@ -61,54 +62,51 @@ Steps .. code-block:: bash - $ $VENV/bin/nosetests tutorial + $ $VENV/bin/py.test tutorial/tests.py -q . - ---------------------------------------------------------------------- - Ran 1 test in 0.141s + 1 passed in 0.14 seconds - OK Analysis ======== -Our ``tests.py`` imports the Python standard unit testing framework. To -make writing Pyramid-oriented tests more convenient, Pyramid supplies -some ``pyramid.testing`` helpers which we use in the test setup and -teardown. Our one test imports the view, makes a dummy request, and sees -if the view returns what we expected. +Our ``tests.py`` imports the Python standard unit testing framework. To make +writing Pyramid-oriented tests more convenient, Pyramid supplies some +``pyramid.testing`` helpers which we use in the test setup and teardown. Our +one test imports the view, makes a dummy request, and sees if the view returns +what we expect. -The ``tests.TutorialViewTests.test_hello_world`` test is a small -example of a unit test. First, we import the view inside each test. Why -not import at the top, like in normal Python code? Because imports can -cause effects that break a test. We'd like our tests to be in *units*, -hence the name *unit* testing. Each test should isolate itself to the -correct degree. +The ``tests.TutorialViewTests.test_hello_world`` test is a small example of a +unit test. First, we import the view inside each test. Why not import at the +top, like in normal Python code? Because imports can cause effects that break a +test. We'd like our tests to be in *units*, hence the name *unit* testing. Each +test should isolate itself to the correct degree. -Our test then makes a fake incoming web request, then calls our Pyramid -view. We test the HTTP status code on the response to make sure it -matches our expectations. +Our test then makes a fake incoming web request, then calls our Pyramid view. +We test the HTTP status code on the response to make sure it matches our +expectations. Note that our use of ``pyramid.testing.setUp()`` and ``pyramid.testing.tearDown()`` aren't actually necessary here; they are only necessary when your test needs to make use of the ``config`` object (it's a Configurator) to add stuff to the configuration state before calling the view. + Extra Credit ============ -#. Change the test to assert that the response status code should be - ``404`` (meaning, not found.) Run ``nosetests`` again. Read the - error report and see if you can decipher what it is telling you. +#. Change the test to assert that the response status code should be ``404`` + (meaning, not found). Run ``py.test`` again. Read the error report and see + if you can decipher what it is telling you. -#. As a more realistic example, put the ``tests.py`` back as you found - it and put an error in your view, such as a reference to a - non-existing variable. Run the tests and see how this is more - convenient than reloading your browser and going back to your code. +#. As a more realistic example, put the ``tests.py`` back as you found it, and + put an error in your view, such as a reference to a non-existing variable. + Run the tests and see how this is more convenient than reloading your + browser and going back to your code. #. Finally, for the most realistic test, read about Pyramid ``Response`` - objects and see how to change the response code. Run the tests and - see how testing confirms the "contract" that your code claims to - support. + objects and see how to change the response code. Run the tests and see how + testing confirms the "contract" that your code claims to support. #. How could we add a unit test assertion to test the HTML value of the response body? -- cgit v1.2.3