forked from sergutsan/groovyck
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexercises_d9.tex
311 lines (260 loc) · 10.2 KB
/
exercises_d9.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
\documentclass{article}
\usepackage[margin=2cm]{geometry}
\usepackage[dvips]{graphicx}
\begin{document}
\section*{Learning goals}
\label{sec:learning-goals}
Before the next day, you should have achieved the following learning
goals:
\begin{itemize}
\item Understand the importance of automated testing.
\item Write your own tests for classes already defined.
\item Execute your own tests for classes already defined.
\end{itemize}
You should be able to finish most of non-star exercises in the lab.
Remember that star exercises are more difficult.
\textbf{Do not try star-exercises unless the other ones are clear to
you}.
\section{Install JUnit 4}
\label{sec:install-junit-4}
Use your favourite search engine to find JUnit (``JUnit download''
will do, and probably just ``JUnit'' will do too).
\begin{itemize}
\item Download the latest stable version of JUnit 4. You may download
it either as a ZIP with a JAR file inside or as the JAR file
directly. The JAR file will have a name
similar to \verb+junit.jar+ (maybe including a version number,
similar to \verb+junit-4.11.jar+).
\item Download the latest stable version of HamCrest too.
\item Place both JAR files in a place where you can find it. It is
probably a good idea to create a folder ``lib'' where you place all
the external libraries that you use (e.g.~\verb+h:\lib+ on windows
or \verb+/opt/lib+ on Unix systems).
\item Now you can add both JAR files to your classpath at the command
line (as in the notes) or by modifying the environment variable
CLASSPATH.
\end{itemize}
\section{Testing mathematical functions}
\label{sec:test-math-funct}
On Day~7 you implemented a simple hash. Write a battery of tests to
verify its behaviour, paying special attention to border cases.
Hint: Implement a loop that tries a fair amount of random numbers
(around two thousand, for the purposes of this exercise) and verify
that the output is within the range.
\section{Practice "Find bugs once"}
\label{sec:practice-find-bugs}
% \subsection*{a)}
The method \verb+getInitials(String)+ has a bug! If you introduce a
name with more than one space between words, it throws an exception.
Create a class that contains the method \verb+getInitials(String)+ as
described in the notes. Create also the test class as described in the
notes.
Then follow the ``find bugs once'' algorithm: reproduce the bug manually,
reproduce the bug programmatically by adding a new test to the testing
class, then fix the bug and check that all tests pass.
%%%
%%%
%%% TODO:
%%% The purpose of the (b) exercise is good, but the actual program
%%% is terrible. The fix is really easy, and the amount of work
%%% needed to refactor it to make it easily testable is large.
%%% TODO: think of a better example.
%%%
%%%
% \subsection*{b) (*)}
% \label{sec:b}
% Another programmer has created a simple program for personal
% accounting. This program asks the user for the number of bills that have not
% been paid yet and calculates the total debt. Look at the Accounting
% and Bill classes below.
% \begin{figure}[hbtp]
% \centering
% \begin{verbatim}
% /**
% * A program for simple personal accounting.
% *
% * Asks the users about their bills, and then
% * says how many bills there are, and what is the
% * total debt.
% */
% public class Accounting {
% /**
% * The first element of the list of bills
% */
% private Bill firstBill = null;
% public static void main(String[] args) {
% Accounting acc = new Accounting();
% acc.launch(args);
% }
% private void launch(String[] args) {
% String concept = "";
% int amount = 0;
% do {
% System.out.println("What's your next bill (type \"END\" to finish)?");
% System.out.print(" Concept: ");
% concept = System.console().readLine();
% if (!concept.equals("END")) {
% System.out.print(" Amount: ");
% String strAmount = System.console().readLine();
% amount = Integer.parseInt(strAmount);
% }
% Bill newBill = new Bill(concept, amount);
% addBillToList(newBill);
% } while (!concept.equals("END"));
% int count = 0;
% int totalDebt = 0;
% for (Bill current = firstBill; current != null; current = current.getNextBill()) {
% count++;
% totalDebt += current.getAmount();
% }
% System.out.println("You have " + count + " bills unpaid (total debt: " + totalDebt + ")");
% }
% \end{verbatim}
% \caption{Class Accounting (1 of 2)}
% \label{fig:accountingggggt}
% \end{figure}
% \begin{figure}[hbtp]
% \centering
% \begin{verbatim}
% private void addBillToList(Bill bill) {
% if (firstBill == null) {
% firstBill = bill;
% return;
% }
% Bill current = firstBill;
% while (current != null) {
% if (current.getNextBill() == null) {
% current.setNextBill(bill);
% return;
% }
% current = current.getNextBill();
% }
% return;
% }
% }
% \end{verbatim}
% \caption{Class Accounting (2 of 2)}
% \label{fig:accountinggggg}
% \end{figure}
% \begin{figure}[hbtp]
% \centering
% \begin{verbatim}
% public class Bill {
% private String concept;
% private int amount;
% private Bill next;
% public Bill(String concept, int amount) {
% this.concept = concept;
% this.amount = amount;
% this.next = null;
% }
% public String getConcept() {
% return concept;
% }
% public int getAmount() {
% return amount;
% }
% public void setNextBill(Bill bill) {
% next = bill;
% }
% public Bill getNextBill() {
% return next;
% }
% }
% \end{verbatim}
% \caption{Class Bill}
% \label{fig:accountingggggtr}
% \end{figure}
% The programmer comes to see you because the program does not work as
% expected: it says that there is one bill too many, and the calculated
% total debt is wrong too. The programmer asks for
% your help. You decide to use the ``find bugs once'' algorithm to find
% the bug, create a test that reproduces the bug,
% and then fix the bug once and for all.
% This is a common situation in companies. There is some software that
% has been developed in the past (maybe by programmers that have left
% the company since) and it needs fixing. The programmers responsible of
% fixing the program have never seen the code before, they are just told
% what it should do.
% Usually the first step is to \emph{refactor} the code to make it
% easier to test; this may involve breaking up methods and classes into
% smaller, simpler methods and classes. For example, you may want to
% separate the ``getting user input'' and the ``create new bill''
% functionalities in method \verb+launch()+ above, so that you can
% test the latter with JUnit; you can never test user input in an
% automated way, but you can test what you do with that input by
% creating fake user data and passing it to your methods.
\section{Test implementations of a given interface}
\label{sec:test-impl-given}
You already know that an interface is a way of describing the
behaviour of a class without any knowledge about the implementation
details. Sometimes, one
party provides the interface of a component and the other party
implements the interface. This is very common in big projects, where
small teams of programmers make parts of a bigger program (e.g.~web
browsers, word processors, multiplayer games), and the different
modules need to communicate with each other. Defining clear and simple
interfaces is usually the first step in the design, as it allows
different teams to work in parallel and then bring their code
together.
Sometimes, the first party does not only define the interface, it also
implements the tests that the implementation (i.e.~the class that
implements the interface) must pass\footnote{When this approach is taken to
its logical conclusion, we are talking about Test-Driven Development
as we will see very soon.}. This is a good idea when the development is
sub-hired to an external company.
Take the role of a project leader and implement the tests for two of
the interfaces you have implemented in past weeks.
\subsection{Stack}
\label{sec:stack3}
The notes from Day~8 implemented a Stack interface in two different
ways. Create a battery of tests that verify that the classes
implementing the interface is working as expected. Use it to test both
implementations.
\subsection{Queue}
\label{sec:stack2}
You implemented a Queue interface ---maybe in two different ways--- on
Day~8. Create a battery of tests that verify that the class(es)
implementing the interface work/s as expected.
\subsection{Set (*)}
\label{sec:stack5}
You implemented a Set interface ---possibly in two different ways--- on
Day~9. Create a battery of tests that verify that the class(es)
implementing the interface work as expected.
\section{Testing dynamic structures}
\label{sec:testing-maps}
Write batteries of tests to verify the functionality of the dynamic
structures you have created in past weeks:
% TODO: Update these dates
\begin{itemize}
\item doubly-linked list (day 7)
\item circular list (day 7)
\item simple map (day 8)
\item sorted list (day 7)
\end{itemize}
Make sure that you test border cases, including situations like:
\begin{itemize}
\item Adding the first element.
\item Removing the last element.
\item Adding the first element and then removing it\ldots and then
adding another one.
\end{itemize}
You should have time to do at least one the four cases in the lab.
\section{More tests (**)}
\label{sec:more-tests-}
If you have finished with the other exercises, write additional
batteries of tests for other programs (in particular, the exercises
marked with a star) that you have written in past
weeks. Some exercises that provide a harder challenge to test properly
are:
\begin{itemize}
\item the anti-aircraft game from day 6
\item any of the sort algorithms from day 7
\item any of the unfair queues from day 8
\item the hash-table (day 8)
\item deletion of elements in a tree (day 9)
\item re-balancing of a tree (day 9)
\item the abstract syntax tree (day 9)
\item the pseudo-git tree (day 9) (**)
\end{itemize}
\end{document}