@@ -4,21 +4,21 @@ Writing Tests for github3.py
44Unit Tests
55----------
66
7- In computer programming, unit testing is a method by which individual
8- units of source code, sets of one or more computer program modules
9- together with associated control data, usage procedures, and operating
10- procedures are tested to determine if they are fit for use. Intuitively,
7+ In computer programming, unit testing is a method by which individual
8+ units of source code, sets of one or more computer program modules
9+ together with associated control data, usage procedures, and operating
10+ procedures are tested to determine if they are fit for use. Intuitively,
1111 one can view a unit as the smallest testable part of an application.
1212
13- -- `Unit Testing on Wikipedia
13+ -- `Unit Testing on Wikipedia
1414 <http://en.wikipedia.org/wiki/Unit_testing> `_
1515
16- In github3.py we use unit tests to make assertions about how the library
17- behaves without making a request to the internet. For example, one assertion
18- we might write would check if custom information is sent along in a request to
16+ In github3.py we use unit tests to make assertions about how the library
17+ behaves without making a request to the internet. For example, one assertion
18+ we might write would check if custom information is sent along in a request to
1919GitHub.
2020
21- An existing test like this can be found in
21+ An existing test like this can be found in
2222``tests/unit/test_repos_release.py ``:
2323
2424.. code :: python
@@ -30,63 +30,63 @@ An existing test like this can be found in
3030 headers = {' Accept' : ' application/vnd.github.manifold-preview' }
3131 )
3232
33- In this test, we check that the library passes on important headers to the API
34- to ensure the request will work properly. ``self.instance `` is created for us
35- and is an instance of the ``Release `` class. The test then calls ``delete `` to
36- make a request to the API. ``self.session `` is a mock object which fakes out a
37- normal session. It does not allow the request through but allows us to verify
38- how github3.py makes a request. We can see that github3.py called ``delete ``
39- on the session. We assert that it was only called once and that the only
33+ In this test, we check that the library passes on important headers to the API
34+ to ensure the request will work properly. ``self.instance `` is created for us
35+ and is an instance of the ``Release `` class. The test then calls ``delete `` to
36+ make a request to the API. ``self.session `` is a mock object which fakes out a
37+ normal session. It does not allow the request through but allows us to verify
38+ how github3.py makes a request. We can see that github3.py called ``delete ``
39+ on the session. We assert that it was only called once and that the only
4040parameters sent were a URL and the custom headers that we are concerned with.
4141
4242Mocks
4343~~~~~
4444
4545Above we talked about mock objects. What are they?
4646
47- In object-oriented programming, mock objects are simulated objects that
48- mimic the behavior of real objects in controlled ways. A programmer
49- typically creates a mock object to test the behavior of some other object,
50- in much the same way that a car designer uses a crash test dummy to
47+ In object-oriented programming, mock objects are simulated objects that
48+ mimic the behavior of real objects in controlled ways. A programmer
49+ typically creates a mock object to test the behavior of some other object,
50+ in much the same way that a car designer uses a crash test dummy to
5151 simulate the dynamic behavior of a human in vehicle impacts.
5252
5353 -- `Mock Object on Wikipedia <http://en.wikipedia.org/wiki/Mock_object >`_
5454
55- We use mocks in github3.py to prevent the library from talking directly with
56- GitHub. The mocks we use intercept requests the library makes so we can verify
57- the parameters we use. In the example above, we were able to check that
58- certain parameters were the only ones sent to a session method because we
55+ We use mocks in github3.py to prevent the library from talking directly with
56+ GitHub. The mocks we use intercept requests the library makes so we can verify
57+ the parameters we use. In the example above, we were able to check that
58+ certain parameters were the only ones sent to a session method because we
5959mocked out the session.
6060
61- You may have noticed in the example above that we did not have to set up the
62- mock object. There is a convenient helper written in ``tests/unit/helper.py ``
61+ You may have noticed in the example above that we did not have to set up the
62+ mock object. There is a convenient helper written in ``tests/unit/helper.py ``
6363to do this for you.
6464
6565Example - Testing the Release Object
6666~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6767
68- Here's a full example of how we test the ``Release `` object in
68+ Here's a full example of how we test the ``Release `` object in
6969``tests/unit/test_repos_release.py ``.
7070
71- Our first step is to import the ``UnitHelper `` class from
72- ``tests/unit/helper.py `` and the ``Release `` object from
71+ Our first step is to import the ``UnitHelper `` class from
72+ ``tests/unit/helper.py `` and the ``Release `` object from
7373``github3/repos/release.py ``.
7474
7575.. code :: python
7676
7777 from .helper import UnitHelper
7878 from github3.repos.release import Release
7979
80- Then we construct our test class and indicate which class we will be testing
80+ Then we construct our test class and indicate which class we will be testing
8181(or describing).
8282
8383.. code :: python
8484
8585 class TestRelease (UnitHelper ):
8686 described_class = Release
8787
88- We can then use the `GitHub API documentation about Releases
89- <http://developer.github.com/v3/repos/releases/> `_ to retrieve example release
88+ We can then use the `GitHub API documentation about Releases
89+ <http://developer.github.com/v3/repos/releases/> `_ to retrieve example release
9090data. We then can use that as example data for our test like so:
9191
9292.. code :: python
@@ -109,8 +109,8 @@ data. We then can use that as example data for our test like so:
109109 " published_at" : " 2013-02-27T19:35:32Z"
110110 }
111111
112- The above code now will handle making clean and brand new instances of the
113- ``Release `` object with the example data and a faked out session. We can now
112+ The above code now will handle making clean and brand new instances of the
113+ ``Release `` object with the example data and a faked out session. We can now
114114construct our first test.
115115
116116.. code :: python
@@ -126,22 +126,22 @@ construct our first test.
126126 Integration Tests
127127-----------------
128128
129- Integration testing is the phase in software testing in which individual
129+ Integration testing is the phase in software testing in which individual
130130 software modules are combined and tested as a group.
131131
132- The purpose of integration testing is to verify functional, performance,
132+ The purpose of integration testing is to verify functional, performance,
133133 and reliability requirements placed on major design items.
134134
135- -- `Integration tests on Wikipedia
135+ -- `Integration tests on Wikipedia
136136 <http://en.wikipedia.org/wiki/Integration_tests> `_
137137
138- In github3.py we use integration tests to ensure that when we make what should
139- be a valid request to GitHub, it is in fact valid. For example, if we were
140- testing how github3.py requests a user's information, we would expect a
141- request for a real user's data to be valid. If the test fails we know either
138+ In github3.py we use integration tests to ensure that when we make what should
139+ be a valid request to GitHub, it is in fact valid. For example, if we were
140+ testing how github3.py requests a user's information, we would expect a
141+ request for a real user's data to be valid. If the test fails we know either
142142what the library is doing is wrong or the data requested does not exist.
143143
144- An existing test that demonstrates integration testing can be found in
144+ An existing test that demonstrates integration testing can be found in
145145``tests/integration/test_repos_release.py ``:
146146
147147.. code :: python
@@ -156,31 +156,31 @@ An existing test that demonstrates integration testing can be found in
156156 assert isinstance (asset, github3.repos.release.Asset)
157157 assert asset is not None
158158
159- In this test we use ``self.recorder `` to record our interaction with GitHub.
160- We then proceed to make the request to GitHub that will exercise the code we
161- wish to test. First we request a ``Repository `` object from GitHub and then
162- using that we request a ``Release `` object. After receiving that release, we
163- exercise the code that lists the assets of a ``Release ``. We verify that each
164- asset is an instance of the ``Asset `` class and that at the end the ``asset ``
165- variable is not ``None ``. If ``asset `` was ``None ``, that would indicate that
166- GitHub did not return any data and it did not exercise the code we are trying
159+ In this test we use ``self.recorder `` to record our interaction with GitHub.
160+ We then proceed to make the request to GitHub that will exercise the code we
161+ wish to test. First we request a ``Repository `` object from GitHub and then
162+ using that we request a ``Release `` object. After receiving that release, we
163+ exercise the code that lists the assets of a ``Release ``. We verify that each
164+ asset is an instance of the ``Asset `` class and that at the end the ``asset ``
165+ variable is not ``None ``. If ``asset `` was ``None ``, that would indicate that
166+ GitHub did not return any data and it did not exercise the code we are trying
167167to test.
168168
169169Betamax
170170~~~~~~~
171171
172- Betamax _ is the library that we use to create the recorder above. It sets up
173- the session object to intercept every request and corresponding response and
174- save them to what it calls cassettes _. After you record the interaction it
172+ Betamax _ is the library that we use to create the recorder above. It sets up
173+ the session object to intercept every request and corresponding response and
174+ save them to what it calls cassettes _. After you record the interaction it
175175never has to speak to the internet again for that request.
176176
177- In github3.py there is a helper class (much like ``UnitHelper ``) in
177+ In github3.py there is a helper class (much like ``UnitHelper ``) in
178178``tests/integration/helper.py `` which sets everything up for us.
179179
180180Example - Testing the Release Object
181181~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
182182
183- Here's an example of how we write an integration test for github3.py. The
183+ Here's an example of how we write an integration test for github3.py. The
184184example can be found in ``tests/integration/test_repos_release.py ``.
185185
186186Our first steps are the necessary imports.
@@ -210,37 +210,37 @@ Then we start writing our test right away.
210210 assert release is not None
211211 assert release.delete() is True
212212
213- Every test has access to ``self.gh `` which is an instance of ``GitHub ``.
214- ``IntegrationHelper `` provides a lot of methods that allow you to focus on
215- what we are testing instead of setting up for the test. The first of those
216- methods we see in use is ``self.token_login `` which handles authenticating
217- with a token. It's sister method is ``self.basic_login `` which handles
218- authentication with basic credentials. Both of these methods will set up the
219- authentication for you on ``self.gh ``.
213+ Every test has access to ``self.gh `` which is an instance of ``GitHub ``.
214+ ``IntegrationHelper `` provides a lot of methods that allow you to focus on
215+ what we are testing instead of setting up for the test. The first of those
216+ methods we see in use is ``self.token_login `` which handles authenticating
217+ with a token. It's sister method is ``self.basic_login `` which handles
218+ authentication with basic credentials. Both of these methods will set up the
219+ authentication for you on ``self.gh ``.
220220
221- The next convenience method we see is ``self.cassette_name ``. It constructs a
222- cassette name for you based on the test class name and the string you provide
221+ The next convenience method we see is ``self.cassette_name ``. It constructs a
222+ cassette name for you based on the test class name and the string you provide
223223it.
224224
225- Every test also has access to ``self.recorder ``. This is the Betamax recorder
226- that has been set up for you to record your interactions. The recorder is
225+ Every test also has access to ``self.recorder ``. This is the Betamax recorder
226+ that has been set up for you to record your interactions. The recorder is
227227started when you write
228228
229229.. code :: python
230230
231231 with self .recorder.use_cassette(cassette_name):
232232 # ...
233233
234- Everything that talks to GitHub should be written inside of the context
235- created by the context manager there. No requests to GitHub should be made
234+ Everything that talks to GitHub should be written inside of the context
235+ created by the context manager there. No requests to GitHub should be made
236236outside of that context.
237237
238- In that context, we then retrieve a repository and create a release for it. We
239- want to be sure that we will be deleting something that exists so we assert
240- that what we received back from GitHub is not ``None ``. Finally we call
238+ In that context, we then retrieve a repository and create a release for it. We
239+ want to be sure that we will be deleting something that exists so we assert
240+ that what we received back from GitHub is not ``None ``. Finally we call
241241``delete `` and assert that it returns ``True ``.
242242
243- When you write your new test and record a new cassette, be sure to add the new
243+ When you write your new test and record a new cassette, be sure to add the new
244244cassette file to the repository, like so:
245245
246246.. code ::
0 commit comments