Assignment: Software Testing: Wishnu Prasetya (Wishnu@cs - Uu.nl) Nov 2009
Assignment: Software Testing: Wishnu Prasetya (Wishnu@cs - Uu.nl) Nov 2009
For this exercise you get a small Java application called Foo’s Participation System. You will get
its source code, along with its Javadoc documentation. Your task is to test this application; this
will be explained in details later.
The Application
This Foo System is not a real business system; it is just a simulation for your training purpose.
It manages a set of customers, services, and customers’ participations on services. It provides basic
functionalities, e.g. to add and remove customers, services, etc. A ’service’ here represents some
business, e.g. an online shop, or a pizza restaurant. The application provides a functionality to
let a customer add/buy a participation to a service. In the real life this means that the customer
would be charged for daily contribution to the services he participates in. In exchange he will get
a proportional share of the services’ profit. He can drop participation at any time.
Currently profit calculation is not included in the system, but it does calculate the contribu-
tion cost for each customer. Furthermore, there is a functionality to award discount tokens to
customers; these give them reduction on the contribution cost they have to pay. The application
provides a functionality to ’resolve’, intended to be invoked by the application owner at the end
of every day. It will calculate the contribution cost of each customer, taking the discount tokens
into account. This will also consume relevant tokens.
A screen shot of the application is provided below. You interact with it through a provided
client program, by typing a command in the command field at the bottom; it will cause the
corresponding functionality to be invoked. See the Appendix for the list of available commands.
1
The class diagram below summarizes the relations between customers, services, participa-
tions, and discounts. Administrating these entities, and doing calculation over them is the pur-
pose of our Foo System.
Administrating those data is an on-going task in the Foo company. So, we need to save the
data when we exit the application, so that we can get them back the next time we start it. Actually
we need to regularly save the data, so that we don’t lose critical business information in case the
application, for whatever reason, crashes.
Although simple, this application is not trivial either. To make it modular, I have split it in lay-
ers stacked as in the typical three tiered architecture shown below. The brain of this application
in in the application logic layer; it is responsible for doing the actual administration of the entities
in the class diagram above. The persistence layer is responsible for saving these data safely in a
database, and for handling queries on those data. It uses an OO database called db4o. The user
interface is implemented in a separate layer.
Calculating Contribution
Each instance of the class Discount represents a discount token. Discount itself is an abstract
class, promising two methods; see below. If t is a discount token, then:
• given a customer c, t.applicable(c) returns true if and only if the customer c is at this
moment eligible to be given the discount promised by t.
• t.calcDiscount(c) returns the cost reduction (in eurocent) this token t would give to c.
A customer c can own a set P of participations and a set D of discount tokens. His total
contribution cost before discount is:
X
R = p.service.price
p∈P
2
This R is also called c’s participation value. Let D0 be the subset of D, consisting of those
discount tokens that are applicable on c. The total discount value of c is:
X
D = min( t.calcDiscount(c), R)
t∈D 0
The contribution cost that he daily owes to the Foo company is then just:
C = R−D
Discounts
Currently two concrete subclasses of Discount are provided:
• Discount 1000. This discount is applicable on a customer whose total participation value
exceeds 1000 euro.
This discount gives 50 euro discount to every 1000 euro participation of a customer. E.g. if
customer c owns participations worth 2000 euro, and he has one instance of Discount 1000,
this will give him 100 euro discount. If he has two instances of this class, he will get 200
euro discount.
• Discount 5pack. This discount is applicable on a customer who owns participations in at
least 5 services, each with the value of at least 100 euro. It will give 10 euro discount.
The best way to setup your testing environment is through Eclipse. Make an Eclipse project
and make the source code of Foo part of your project.
You need to compile the source code first. Include the db4o’s jar in your class path.
Once compiled, running the class ParticipationSystem will launch Foo; don’t forget to
include db4o’s jar in your class path.
Use JUnit to do your testing. Use Emma to see the coverage of your tests. JUnit is already
integrated in Eclipse. Emma can be installed as a pluggin of Eclipse (this should have been done
on our labs PCs).
Task
Test the methods (10) listed below. You don’t have to do them all, but you can only get your full
point (10 pt) if you do.
3
(b) getDiscountValue
(c) getCostToPay
(d) getParticipationGroups
2. from the class Discount 1000:
(a) applicable
(b) calcDiscount
3. from the class Discount 5pack:
(a) applicable
(b) calcDiscount
4. from the class ApplicationLogic:
(a) removeService
(b) resolve
They should be tested whether they meet their (informal) specifications as described in the pro-
vided JavaDoc documentation for each. Your test should be adequate —we will use Emma’s
branch coverage as our coverage criterion.
Grading
Each method from the list above is worth 1pt, and is graded as follows:
• Your tests should give full (100%) coverage on the method. Else, obviously your tests are
incomplete. For this you will get no point (0).
• It is important that you provide a good test suite against the method’ specification. If you
only partially check the specification, you may miss fatal bugs. So, you will only get 0.5
pt if your tests are only partial. If your test expectations are really trivial (these are test
expectations that will never reveal any bug), you get no point.
There are some templates of JUnit test classes that you can use as starting point. See the
directory mytest.
Appendix
Foo’s commands
• help print a list of available commands.
• show:c:* list all customers.
• show:s:* list all services.
• show:c:id show the information of the customer with the given id. The id is an integer.
• show:s:id show the information of the service with the given id. The id is an integer.
4
• add:c:name:email add a customer with the given name and email.
• add:s:name:price add a service with the given name and daily contribution price (in
euro-cent).
• add:p:cid:sid add one unit of participation to the service sid to the costumer cid.