Win a copy of Pro Spring MVC with WebFlux: Web Development in Spring Framework 5 and Spring Boot 2 this week in the Spring forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Jeanne Boyarsky
  • Liutauras Vilda
Sheriffs:
  • Rob Spoor
  • Bear Bibeault
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:
  • Frits Walraven
  • Himai Minh

Examples on what to test when testing a project

 
Ranch Hand
Posts: 109
1
Netbeans IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You've probably seen this a million times but I'll ask anyway because I don't understand. I've searched online but all I could find is the usual calculator test and the junit syntax. That's not what I'm interested in. I want to get started with tests because it really is important.

I know the very basic ideas behind testing (take this lightly, my brain is a mess). Unit testing is supposed to test methods or classes, there's behaviour testing that tests between the UI and the backend, there's mocking etc.

What I somehow want to know is what to test in a program. Let's say I have an online store, a user logs in, puts stuff in a cart and then checks out by paying. Which is the testable code in this occasion? Should I test the session bean's method that sums and returns the price of the items? Should I test the method that removes stuff from the cart?

As you can see, I'm really confused. I'm re-writing my thesis project (I presented last year, this isn't a homework question) and I would like to have tests, I'll understand testing a lot better since it's the code I've written myself.
 
Sheriff
Posts: 16252
271
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My rule of thumb: Test the interesting behavior in your program.

Getters and setters that only access a field directly and do nothing else are NOT interesting. Ones that perform calculations or enlist collaborators to perform subtasks are interesting. I tend to test from the "inside" of my application, deferring the testing of infrastructure and interaction classes (data access, user interactions, etc.) for later.

Now to get into some "heavier" stuff.

For me testing is not so much about proving correctness as it is a way to find bugs and opportunities to refactor. Tests that are written after the code they are exercising tend to be more focused on implementation details and as such, they are more brittle and often break when the implementation changes. Tests that are written before or alongside the code being tested tend to be more resilient. Test-Driven Development (TDD) provides the framework in which to write tests like this. These tests are more like mini experiments to see if the awesome design you had in your head can really stand up when it is fleshed out in actual code. These tests often look like examples for your program's API. They show you the conditions under which behaviors can be invoked, the kind of stimuli your program responds to and what are its reactions to various conditions. Good tests also show conditions under which errors can be expected and what kind of exceptions you can expect to be thrown.

For me, the value of testing is not so much in verifying that my program works. Rather, I use tests more to help me find bugs and opportunities to refactor. I use them to find ways to make my design clean and my code clear and expressive. By focusing on that, correctness usually comes as a natural consequence.

Lastly, collaborative development (pair programming / mob programming) tends to produce many useful conversations that can result in better tests and designs. Here's one example from these forums: https://coderanch.com/t/643124/design/implement-vending-application - I should warn you, that's a veery long thread with many conversations in between test code examples. If you have the patience to read through it and follow the thought process, you might get something out of it.
 
Junilu Lacar
Sheriff
Posts: 16252
271
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Could you post some code that you think would be something you'd want to test? Then maybe post examples of tests you'd write against that code. That would provide a concrete base on which to have a discussion about tests and testing.
 
Vasilis Souvatzis
Ranch Hand
Posts: 109
1
Netbeans IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, now I'm really intrigued! Since I do my developing by myself, I think testing might help me flesh out my designs (I don't really have designs, just a basic idea that I start coding on and add functionality as I go) because I already have a basic interaction of the classes in my mind.

Let's take my thesis project. I presented to my faculty last year and in fact was asked at NetBeans Day Athens 2015 if I did write any tests, to which I replied that I didn't. It needs lots of refactoring and is riddled with bugs, so I guess it's a perfect candidate

What I think needs to be tested:
The finalizePurchase() in the Checkout class because ideally, it should only complete when the payment method is completed, the users are persisted to the DB and of course there are items in the cart.

I also think the ShoppingCart class needs to be tested but I'm not sure, maybe it's too simplistic for actual tests?

That's all I can think for now. Like I said, I had a basic idea and just added stuff as I coded. Initially, I wanted to add a lot more functionality but I hit various roadblocks and had to settle for this.
 
Vasilis Souvatzis
Ranch Hand
Posts: 109
1
Netbeans IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thought of another thing I wanted to add, but I'm actually adding it in the re-write project I'm working on.

Discounts on the final purchase price.

If the user has selected >5 items, I'll do a 10% discount. If it's >10 a 20% and if it's >20 a 30% discount.
 
Junilu Lacar
Sheriff
Posts: 16252
271
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The classes you mentioned certainly look like they have some interesting behavior to test. Why don't you try writing some tests and we can discuss what you did.
 
Vasilis Souvatzis
Ranch Hand
Posts: 109
1
Netbeans IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Alright, I'll write in pseudo-code since I don't know how to write actual tests in JUnit or something similar.

Test CalculateDiscount:
cartSizeIsZero: if cart.size == 0 : fail test (because you can't buy nothing)
cartSizeLessThan5: if cart.size < 5 : pass test (no discount application though)
cartSizeLessThan10: if cart.size < 10 : pass test (apply 10% discount)
cartSizeLessThan20: if cart.size < 20: pass test (apply 20% discount)
cartSizeMoreThan20: if cart.size >= 20 : pass test (apply 30% discount)

Test Checkout:
userCannotBuyCoursesIfNotInDatabase: if user doesn't exist in DB : fail test (because we can't relate a non-existent user with the purchase)
userBuysCoursesIfInDatabase: if user is registered : pass test and merge their DB record with the courses

Does this logic make any sense?
 
Junilu Lacar
Sheriff
Posts: 16252
271
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Vasilis Souvatzis wrote:Alright, I'll write in pseudo-code since I don't know how to write actual tests in JUnit or something similar.


That's fine. At some point, you will have to learn though.

Vasilis Souvatzis wrote:
Test CalculateDiscount:
cartSizeIsZero: if cart.size == 0 : fail test (because you can't buy nothing)
cartSizeLessThan5: if cart.size < 5 : pass test (no discount application though)
cartSizeLessThan10: if cart.size < 10 : pass test (apply 10% discount)
cartSizeLessThan20: if cart.size < 20: pass test (apply 20% discount)
cartSizeMoreThan20: if cart.size >= 20 : pass test (apply 30% discount)


This is still good enough to start a conversation about design and refactoring, in particular, the nomenclature you are using and the semantics of the names in the contexts that you use them.

One thing I often see is implementation detail exerting too much influence in the way things are named. This isn't necessarily a bad thing but often, as it is in this case, it can be. There's a subtle dissonance in the phrase "cart size" and the idea it represents.

In normal conversations, "cart size" would be more associated with large, medium, small.  A cashier would never ask you "How big is your cart?" if he/she wanted to know how many items you had in it.  "How many items do you have?" is the question you're most likely to be asked, right?

In all likelihood, you use the phrase "cart size" because you used a list to help you represent a cart and a Java List has a size() attribute. So, the idea of "how many items are in the cart" is represented by the implementation detail that is List.size().  This may seem nitpicky but there's a tangible effect that this dissonance has on our brains and how easily we are able to read code.  Look at this example of the Stroop Effect: https://faculty.washington.edu/chudler/words.html

So, with this in mind, what name or noun phrase can you use to eliminate the cognitive dissonance?
 
Vasilis Souvatzis
Ranch Hand
Posts: 109
1
Netbeans IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes I'm sorry, I used "cart.size" because I used a List to store the items. And omitted the parentheses because I knew what I was referring to, I shouldn't assume it'd be understandable out of context for everyone. My bad.

To answer your question, I think a better naming would be "number of items" instead of "cart size". Yes, I think it makes more sense because I may understand what I'm doing but it may not be the case for an outsider.
 
Junilu Lacar
Sheriff
Posts: 16252
271
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Now you have an idea of how collaborative programming can improve the quality of code produced. If we were sitting down trying to write tests together, that seemingly trivial matter of changing the term we use would set the stage for us moving forward. I will assume you are starting to read up on how to write JUnit tests so I won't explain the technical details of this:

This might be what some of the initial tests I'd suggest would look like. Then I'd wait for your input. Specifically, what do these names do to your thinking about the program's purpose, design, and API?
 
You showed up just in time for the waffles! And this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic