|
1 | 1 | [[appendix4]]
|
2 | 2 | [appendix]
|
3 |
| -What to Do Next |
4 |
| ---------------- |
5 |
| - |
6 |
| -((("Test-Driven Development (TDD)", "future investigations", id="TDDfuture35")))Here |
7 |
| -I offer a few suggestions for things to investigate next, to develop your |
8 |
| -testing skills, and to apply them to some of the cool new technologies in web |
9 |
| -development (at the time of writing!). |
10 |
| - |
11 |
| -I hope to turn each one of these into at least some sort of blog post, |
12 |
| -if not a future appendix to the book. I hope to also produce code examples for |
13 |
| -all of them, as time goes by. So do check out |
14 |
| -http://www.obeythetestinggoat.com, and see if there |
15 |
| -are any updates. |
16 |
| - |
17 |
| -Or, why not try to beat me to it, and write your own blog post chronicling |
18 |
| -your attempt at any one of these? |
19 |
| - |
20 |
| -((("getting help")))I'm |
21 |
| -very happy to answer questions and provide tips and guidance on all |
22 |
| -these topics, so if you find yourself attempting one and getting stuck, |
| 3 | +== What to Do Next |
| 4 | + |
| 5 | +((("Test-Driven Development (TDD)", "future investigations", id="TDDfuture35"))) |
| 6 | +Here I offer a few suggestions for things to investigate next, |
| 7 | +to develop your testing skills, |
| 8 | +and to apply them to some of the cool new technologies in web development |
| 9 | +(at the time of writing!). |
| 10 | + |
| 11 | +I might write an article about some of these in the future. |
| 12 | +But why not try to beat me to it, |
| 13 | +and write your own blog post chronicling your attempt at any one of these? |
| 14 | + |
| 15 | +((("getting help"))) |
| 16 | +I'm very happy to answer questions and provide tips and guidance |
| 17 | +on all these topics, |
| 18 | +so if you find yourself attempting one and getting stuck, |
23 | 19 | please don't hesitate to get in touch at [email protected]!
|
24 | 20 |
|
25 | 21 |
|
26 | 22 |
|
27 |
| -Notifications--Both on the Site and by Email |
28 |
| -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 23 | +=== Switch to Postgres |
29 | 24 |
|
30 |
| - |
31 |
| - |
32 |
| -It would be nice if users were notified when someone shares a list with |
33 |
| -them. |
34 |
| - |
35 |
| -You can use django-notifications to show a message to users the next |
36 |
| -time they refresh the screen. You'll need two browsers in your FT for this. |
37 |
| - |
38 |
| -And/or, you could send notifications by email. Investigate Django's |
39 |
| -email test capabilities. Then, decide this is so critical that you need |
40 |
| -real tests with real emails. Use the IMAPClient library to fetch actual |
41 |
| -emails from a test webmail account. |
42 |
| - |
43 |
| - |
44 |
| - |
45 |
| -Switch to Postgres |
46 |
| -~~~~~~~~~~~~~~~~~~ |
47 |
| - |
48 |
| - |
49 |
| - |
50 |
| -SQLite is a wonderful little database, but it won't deal well once you |
| 25 | +SQLite is a wonderful little database, but it won't deal well once you |
51 | 26 | have more than one web worker process fielding your site's requests.
|
52 |
| -Postgres is everyone's favourite database these days, so find out how |
53 |
| -to install and configure it. |
54 |
| - |
55 |
| -You'll need to figure out a place to store the usernames and passwords for your |
56 |
| -local, staging, and production Postgres servers. Since, for security, you |
57 |
| -probably don't want them in your code repository, look into ways of modifying |
58 |
| -your deploy scripts to pass them in at the command line. Environment variables |
59 |
| -are one popular solution for where to keep them... |
| 27 | +Postgres is everyone's favourite database these days, |
| 28 | +so find out how to install and configure it. |
60 | 29 |
|
61 |
| -Experiment with keeping your unit tests running with SQLite, and compare how |
62 |
| -much faster they are than running against Postgres. Set it up so that your |
63 |
| -local machine uses SQLite for testing, but your CI server uses Postgres. |
| 30 | +You'll need to figure out a place to store the usernames and passwords |
| 31 | +for your local, staging, and production Postgres servers. |
| 32 | +Take a look at <<chapter_12_ansible>> for inspiration. |
64 | 33 |
|
| 34 | +Experiment with keeping your unit tests running with SQLite, |
| 35 | +and compare how much faster they are than running against Postgres. |
| 36 | +Set it up so that your local machine uses SQLite for testing, |
| 37 | +but your CI server uses Postgres. |
65 | 38 |
|
66 |
| -Run Your Tests Against Different Browsers |
67 |
| -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 39 | +Does any of your functionality actually depend on postgres-specific features? |
| 40 | +What should you do then? |
68 | 41 |
|
69 | 42 |
|
70 |
| -Selenium supports all sorts of different browsers, including Chrome and |
71 |
| -Internet Exploder. Try them both out and see if your FT suite behaves |
72 |
| -any differently. |
| 43 | +=== Run Your Tests Against Different Browsers |
73 | 44 |
|
74 |
| - |
75 |
| -You should also check out a "headless" browser like PhantomJS. |
| 45 | +Selenium supports all sorts of different browsers, |
| 46 | +including Chrome, Safari, and Internet Exploder. |
| 47 | +Try them all out and see if your FT suite behaves any differently. |
76 | 48 |
|
77 | 49 | In my experience, switching browsers tends to expose all sorts of race
|
78 | 50 | conditions in Selenium tests, and you will probably need to use the
|
79 |
| -interaction/wait pattern a lot more (particularly for PhantomJS). |
80 |
| - |
81 |
| - |
82 |
| -404 and 500 Tests |
83 |
| -~~~~~~~~~~~~~~~~~ |
| 51 | +interaction/wait pattern a lot more. |
84 | 52 |
|
85 | 53 |
|
86 |
| -A professional site needs good-looking error pages. Testing a 404 page is |
87 |
| -easy, but you'll probably need a custom "raise an exception on purpose" view |
88 |
| -to test the 500 page. |
89 | 54 |
|
| 55 | +=== The Django Admin Site |
90 | 56 |
|
| 57 | +Imagine a story where a user emails you wanting to "claim" an anonymous list. |
| 58 | +Let's say we implement a manual solution to this, |
| 59 | +involving the site administrator manually changing the record using the Django admin site. |
91 | 60 |
|
92 |
| -The Django Admin Site |
93 |
| -~~~~~~~~~~~~~~~~~~~~~ |
| 61 | +Find out how to switch on the admin site, and have a play with it. |
| 62 | +Write an FT that shows a normal, non–logged-in user creating a list, |
| 63 | +then have an admin user log in, go to the admin site, and assign the list to the user. |
| 64 | +The user can then see it in their "My Lists" page. |
94 | 65 |
|
95 | 66 |
|
96 |
| -Imagine a story where a user emails you wanting to "claim" an anonymous |
97 |
| -list. Let's say we implement a manual solution to this, involving the site |
98 |
| -administrator manually changing the record using the Django admin site. |
99 |
| - |
100 |
| -Find out how to switch on the admin site, and have a play with it. Write an FT |
101 |
| -that shows a normal, non–logged-in user creating a list, then have an admin |
102 |
| -user log in, go to the admin site, and assign the list to the user. The user |
103 |
| -can then see it in their "My Lists" page. |
104 |
| - |
105 |
| - |
106 |
| - |
107 |
| -Write Some Security Tests |
108 |
| -~~~~~~~~~~~~~~~~~~~~~~~~~ |
109 | 67 |
|
| 68 | +=== Write Some Security Tests |
110 | 69 |
|
111 | 70 | Expand on the login, my lists, and sharing tests--what do you need to write to
|
112 | 71 | assure yourself that users can only do what they're authorized to?
|
113 | 72 |
|
114 | 73 |
|
115 | 74 |
|
116 |
| -Test for Graceful Degradation |
117 |
| -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
118 |
| - |
119 |
| -What would happen if our email server goes down? Can we at least show an apologetic |
120 |
| -error message to our users? |
121 |
| - |
122 |
| - |
| 75 | +=== Test for Graceful Degradation |
123 | 76 |
|
| 77 | +What would happen if our email server goes down? |
| 78 | +Can we at least show an apologetic error message to our users? |
124 | 79 |
|
125 |
| -Caching and Performance Testing |
126 |
| -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
127 | 80 |
|
128 | 81 |
|
| 82 | +=== Caching and Performance Testing |
129 | 83 |
|
130 |
| -Find out how to install and configure `memcached`. Find out how to use |
131 |
| -Apache's `ab` to run a performance test. How does it perform with and without |
132 |
| -caching? Can you write an automated test that will fail if caching is not |
133 |
| -enabled? What about the dreaded problem of cache invalidation? Can tests |
134 |
| -help you to make sure your cache invalidation logic is solid? |
135 | 84 |
|
| 85 | +Find out how to install and configure `memcached`. |
| 86 | +Find out how to use Apache's `ab` to run a performance test. |
| 87 | +How does it perform with and without caching? |
| 88 | +Can you write an automated test that will fail if caching is not enabled? |
| 89 | +What about the dreaded problem of cache invalidation? |
| 90 | +Can tests help you to make sure your cache invalidation logic is solid? |
136 | 91 |
|
137 | 92 |
|
138 |
| -JavaScript MVC Frameworks |
139 |
| -~~~~~~~~~~~~~~~~~~~~~~~~~ |
140 | 93 |
|
| 94 | +=== JavaScript Frameworks |
141 | 95 |
|
| 96 | +Check out React, Vue.js, or perhaps my old favourite, Elm. |
142 | 97 |
|
143 | 98 |
|
144 |
| -JavaScript libraries that let you implement a Model-View-Controller |
145 |
| -pattern on the client side are all the rage these days. To-do lists are |
146 |
| -one of the favourite demo applications for them, so it should be pretty easy |
147 |
| -to convert the site to being a single-page site, where all list additions |
148 |
| -happen in JavaScript. |
149 | 99 |
|
150 |
| -Pick a framework--perhaps Backbone.js or Angular.js--and spike in an |
151 |
| -implementation. Each framework has its own preferences for how to write |
152 |
| -unit tests, so learn the one that goes along with it, and see how you like |
153 |
| -it. |
154 | 100 |
|
| 101 | +=== Async and Websockets |
155 | 102 |
|
| 103 | +Supposing two users are working on the same list at the same time. |
| 104 | +Wouldn't it be nice to see real-time updates, |
| 105 | +so if the other person adds an item to the list, you see it immediately? |
| 106 | +A persistent connection between client and server using websockets |
| 107 | +is the way to get this to work. |
156 | 108 |
|
157 |
| -Async and Websockets |
158 |
| -~~~~~~~~~~~~~~~~~~~~ |
| 109 | +Check out Django's aysnc features see if you can them to implement dynamic notifications. |
159 | 110 |
|
| 111 | +To test it, you'll need two browser instances |
| 112 | +(like we used for the list sharing tests), |
| 113 | +and check that notifications of the actions from one appear in the other, |
| 114 | +without needing to refresh the page... |
160 | 115 |
|
161 |
| -Supposing two users are working on the same list at the same time. Wouldn't |
162 |
| -it be nice to see real-time updates, so if the other person adds an item to |
163 |
| -the list, you see it immediately? A persistent connection between client and |
164 |
| -server using websockets is the way to get this to work. |
165 | 116 |
|
166 |
| -Check out one of the Python async web servers--Tornado, gevent, Twisted--and |
167 |
| -see if you can use it to implement dynamic notifications. |
168 | 117 |
|
169 |
| -To test it, you'll need two browser instances (like we used for the list |
170 |
| -sharing tests), and check that notifications of the actions from one |
171 |
| -appear in the other, without needing to refresh the page... |
| 118 | +=== Switch to Using pytest |
172 | 119 |
|
173 | 120 |
|
| 121 | +`pytest` lets you write unit tests with less boilerplate. |
| 122 | +Try converting some of your unit tests to using 'py.test'. |
| 123 | +You may need to use a plugin to get it to play nicely with Django. |
174 | 124 |
|
175 |
| -Switch to Using py.test |
176 |
| -~~~~~~~~~~~~~~~~~~~~~~~ |
177 | 125 |
|
| 126 | +=== Check Out coverage.py |
178 | 127 |
|
179 |
| -'py.test' lets you write unit tests with less boilerplate. Try converting some |
180 |
| -of your unit tests to using 'py.test'. You may need to use a plugin to get it |
181 |
| -to play nicely with Django. |
182 |
| - |
183 |
| - |
184 |
| -Check Out coverage.py |
185 |
| -~~~~~~~~~~~~~~~~~~~~~ |
186 |
| - |
187 |
| - |
188 |
| - |
189 |
| -Ned Batchelder's `coverage.py` will tell you what your 'test coverage' is—what percentage of your code is covered by tests. Now, in theory, because |
190 |
| -we've been using rigorous TDD, we should always have 100% coverage. But it's |
191 |
| -nice to know for sure, and it's also a very useful tool for working on projects |
| 128 | +Ned Batchelder's `coverage.py` will tell you what your 'test coverage' is--what |
| 129 | +percentage of your code is covered by tests. |
| 130 | +Now, in theory, because we've been using rigorous TDD, |
| 131 | +we should always have 100% coverage. |
| 132 | +But it's nice to know for sure, |
| 133 | +and it's also a very useful tool for working on projects |
192 | 134 | that didn't have tests from the beginning.
|
193 | 135 |
|
194 | 136 |
|
195 |
| -Client-Side Encryption |
196 |
| -~~~~~~~~~~~~~~~~~~~~~~ |
197 |
| - |
| 137 | +=== Client-Side Encryption |
198 | 138 |
|
199 | 139 | Here's a fun one: what if our users are paranoid about the NSA, and decide they
|
200 | 140 | no longer want to trust their lists to The Cloud? Can you build a JavaScript
|
201 | 141 | encryption system, where the user can enter a password to encypher their list
|
202 |
| -item text before it gets sent to the server? |
| 142 | +item text before it gets sent to the server? |
203 | 143 |
|
204 |
| -One way of testing it might be to have an "administrator" user that goes to |
| 144 | +One way of testing it might be to have an "administrator" user that goes to |
205 | 145 | the Django admin view to inspect users' lists, and checks that they are stored
|
206 | 146 | encrypted in the database.
|
207 | 147 |
|
208 | 148 |
|
209 | 149 |
|
210 |
| -Your Suggestion Here |
211 |
| -~~~~~~~~~~~~~~~~~~~~ |
| 150 | +=== Your Suggestion Here |
212 | 151 |
|
213 |
| -What do you think I should put here? Suggestions, please!((("", startref="TDDfuture35"))) |
| 152 | +What do you think I should put here? |
| 153 | +Suggestions, please! |
| 154 | +((("", startref="TDDfuture35"))) |
214 | 155 |
|
0 commit comments