• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Implementing Model View Controller With Test Methodologies

 
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Greetings, I started this project to learn Java, Swing, Model View Controller, and writing tests in the form of...
TestSuites[TestSets[TestCases]]
OffHandedQuickTests

Upon refactoring the classes in different packages, I noticed I had to change everything to public (If I wanted the tests to be in their own package). The package tree is shown below:


If I wanted the "CharacterTestSuite(s)" to test all classes in the application package, should I move them into the application package, so I can change the methods to private/protected?
 
Bartender
Posts: 4116
72
Mac TypeScript Chrome Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Not sure what you mean by moving Classes in to different directories, but you shouldn't make methods private/public just because you need to run tests.

And one approach to manage your tests would be put the test Classes in a similar package as with the source but under the test directory.
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Vijitha Kumara wrote:Not sure what you mean by moving Classes in to different directories, but you shouldn't make methods private/public just because you need to run tests.

And one approach to manage your tests would be put the test Classes in a similar package as with the source but under the test directory.



So I didn't say directories, but it's my understanding that directories == packages (java terminology)? So maybe you do don't understand the purpose of why I am doing this?
The purpose of moving classes into different packages is to give a little bit of a cleaner architecture using model view controller (I'm new to this so bare with me here).

I agree that I shouldn't turn methods from private/protect to public just because I need to run tests. That is why I was wondering if there was a way to run the tests from their own package "Tests", or should I keep the test classes in the same package as the classes they are testing?

"And one approach to manage your tests would be put the test Classes in a similar package as with the source but under the test directory."

Hmm, I thought package == directory? I'm not sure what you mean by this:


Do you by any chance mean if I moved the "Tests" package under the "Application" package so the "Tests" Package become a child of the "Application" package? Then if the architecture looked like...
Application Package
   Test Package
       AriesTestSuite Class
       BarretTestSuite Class
       ect... Classes
   Accessories Class
   Armor Class
   ect... Classes

Would this allow the Test Classes to see the private/protected methods of the Application Classes?
 
Marshal
Posts: 4491
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Vijitha Kumara wrote:And one approach to manage your tests would be put the test Classes in a similar package as with the source but under the test directory.


Sam Parson wrote:Hmm, I thought package == directory?



What Vijitha is saying is to put the application code and the test code in the same package; then you can take advantage of package-private access to peek inside or mock settings with the class under test.

Here's an example - MyApp and MyAppTest have the same package (com.example), but different directories:

.
└── src
   ├── main
   │   └── java
   │       └── com
   │           └── example
   │               └──
MyApp.class
   └── test
       └── java
           └── com
               └── example
                   └──
MyAppTest.class
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ron McLeod wrote:

Vijitha Kumara wrote:And one approach to manage your tests would be put the test Classes in a similar package as with the source but under the test directory.


Sam Parson wrote:Hmm, I thought package == directory?



What Vijitha is saying is to put the application code and the test code in the same package; then you can take advantage of package-private access to peek inside or mock settings with the class under test.

Here's an example - MyApp and MyAppTest have the same package (com.example), but different directories:

.
└── src
   ├── main
   │   └── java
   │       └── com
   │           └── example
   │               └──
MyApp.class
   └── test
       └── java
           └── com
               └── example
                   └──
MyAppTest.class



Below is the problem I face when doing this...



 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sam Parson wrote:

Ron McLeod wrote:

Vijitha Kumara wrote:And one approach to manage your tests would be put the test Classes in a similar package as with the source but under the test directory.


Sam Parson wrote:Hmm, I thought package == directory?



What Vijitha is saying is to put the application code and the test code in the same package; then you can take advantage of package-private access to peek inside or mock settings with the class under test.

Here's an example - MyApp and MyAppTest have the same package (com.example), but different directories:

.
└── src
   ├── main
   │   └── java
   │       └── com
   │           └── example
   │               └──
MyApp.class
   └── test
       └── java
           └── com
               └── example
                   └──
MyAppTest.class



Below is the problem I face when doing this...





Small change in my code, but the issue is still the same...



 
Ron McLeod
Marshal
Posts: 4491
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Are the two classes in the same package?
 
Ron McLeod
Marshal
Posts: 4491
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you are going to use the structure in the example, you will need to configure your IDE with two java source locations: src/main/java, and src/test/java.

For example - with Eclipse, it would look something like this:



 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ron McLeod wrote:If you are going to use the structure in the example, you will need to configure your IDE with two java source locations: src/main/java, and src/test/java.

For example - with Eclipse, it would look something like this:





Hmmm I guess I'm not sure how I can do this with intellij. Here is where I am at:
https://i.imgur.com/IAeFGH3.png

If I try to add another directory with the same name (like you did with yours), I get that error shown.
 
Vijitha Kumara
Bartender
Posts: 4116
72
Mac TypeScript Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I can't verify this with IntelliJ now, but you can try creating a maven project via command line (mvn quickstart), and try importing that in to the IDE and see whether any errors are there.
 
Ron McLeod
Marshal
Posts: 4491
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Maybe one of these posts can help you:

    IntelliJ integration test folder alongside main and test
    How to create a test directory in Intellij 13?
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've tried every combination I can think of. Here is a sample of what I have tried:



I still can't get it to work properly.
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I got it working:



However it looks like I won't be able to directly test private methods. I can only write a testcase using a protected method that calls that private method in the same class.
 
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sam Parson wrote:However it looks like I won't be able to directly test private methods. I can only write a testcase using a protected method that calls that private method in the same class.



There's a lot of people who would say you shouldn't need to test private methods anyway. You ought only to be testing methods which are exposed to the world, i.e. methods which are part of the class's documented API. Private methods are just implementation details, and testing shouldn't be concerned with implementation details.

Of course like anything else there are people who wouldn't agree with that. I'm not going to argue with them either, but I would still suggest that if you want to test private methods it may be that you're looking at the code too much and not looking at the documentation enough. In other words, there should documentation for the class which says "If you call this method in such a way then these things should happen and the returned value should be such and such". The documentation shouldn't mention private methods -- look at the documentation for the standard Java API and you'll see it doesn't.
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Sam Parson wrote:However it looks like I won't be able to directly test private methods. I can only write a testcase using a protected method that calls that private method in the same class.



There's a lot of people who would say you shouldn't need to test private methods anyway. You ought only to be testing methods which are exposed to the world, i.e. methods which are part of the class's documented API. Private methods are just implementation details, and testing shouldn't be concerned with implementation details.

Of course like anything else there are people who wouldn't agree with that. I'm not going to argue with them either, but I would still suggest that if you want to test private methods it may be that you're looking at the code too much and not looking at the documentation enough. In other words, there should documentation for the class which says "If you call this method in such a way then these things should happen and the returned value should be such and such". The documentation shouldn't mention private methods -- look at the documentation for the standard Java API and you'll see it doesn't.



I actually had this same discussion with my friend last night. This debate has been going on for quite some time apparently. 100% code test coverage vs saying no to private method testing. I will give one example in my program on why I think I should test a private method...

My program is a calculator for calculating the next possible stats during a level up for a character in the game final fantasy 7. This is the level up algorithm (for the HP stat):
       // (int[]) eightHpLevelUpResults -> function returns this variable -> variable holds the eight possible values hp will increase to after level up (capped at 9999)
       // (String) characterName -> method arguments()
       // (int) nextLevel -> method arguments()
       // (int) hpValue -> method arguments()
       // (int) characterNameIndex -> get from getCharacterNameIndex(characterName)
       // (int) levelBracketIndex -> get from getLevelUpBracketIndex(nextLevel)
       // (int) hpBase -> get from hpBaseTable[characterNameIndex][levelBracketIndex] class variable
       // (int) hpGradient -> get from hpGradientTable[characterNameIndex][levelBracketIndex] class variable
       // (int) hpBaseline -> hpBase + ((nextLevel - 1) * hpGradient)
       // (int) Rnd(1..8) -> use for loop with rndNum[]
           // (int) hpDifference -> rndNumber + ((int)( 100 * (hpBaseline / (double)hpValue)) - 100) -> capped range (0 through 11)
           // (double) hpIncreaseRate ->  get from getHpIncreaseRate(hpDifference)  -> capped range (0.40 through 1.50)



So where does the testing of a private method come in that I think should be tested? Lets take a look at



So would we want to write tests for this ensuring the numbers 0-11 will be returned? Should we write tests for when calculations are made that would end up returning numbers out of the boundaries of 0-11? So we will know how should this method handle out of boundary numbers?

This is an example of why I think testing a private method might come useful.
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, let's put it this way: if that method returned 12, would it have a noticeable effect on the output of one of the public methods? If so, then you could consider testing for the absence of that effect.

Or let's put it another way: if that code wasn't in a method, but it was inline where line 11 is now, would you be asking how to test a section of code inside a public method?
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:Well, let's put it this way: if that method returned 12, would it have a noticeable effect on the output of one of the public methods? If so, then you could consider testing for the absence of that effect.

Or let's put it another way: if that code wasn't in a method, but it was inline where line 11 is now, would you be asking how to test a section of code inside a public method?



To answer the first question It would give a runtime index out of bounds error here:


To answer the second question, I wouldn't write a test case inside the public method using it. The best design I can think of offhand to test the private method would be to write a protected method bottom of the class for the sole purpose of accessing the the private method and returning it's value. Then use JUnit to write testcases from another class in another package. Before shipping the code though, I might have to comment out those protected methods for testing private methods. This is just a design decision I have been running my brain around, but undecided atm.

My mentor/friend was saying this would be more for QA testing and not actual unit testing or tdd. He said unit testing and tdd is running tests just to make sure it works. But running tests outside the boundary scope is more the job of QA testers who should try and break your program. I'd like to think I can automate this somehow, but if pressured for time, managing test methods at the end of every class before deployment would probably cause a headache, and I would leave it to the QA people.
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sam Parson wrote:To answer the first question It would give a runtime index out of bounds error ...



Which would then percolate up until it reached a public method, which you would be testing, and which one of your test cases would catch it. But I see something about random numbers there, so conceivably it would be an error which couldn't be reproduced reliably. That's a whole separate can of worms for testing, though.
 
Sheriff
Posts: 17644
300
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

Sam Parson wrote:My mentor/friend was saying this would be more for QA testing and not actual unit testing or tdd. He said unit testing and tdd is running tests just to make sure it works. But running tests outside the boundary scope is more the job of QA testers who should try and break your program. I'd like to think I can automate this somehow, but if pressured for time, managing test methods at the end of every class before deployment would probably cause a headache, and I would leave it to the QA people.


This is a bit odd. If you are doing TDD, leaving boundary conditions to someone else seems like a cop out. Leaving boundary conditions to QA folks is a very traditional style development attitude. Look up CORRECT testing of boundary conditions.

QA folks should really spend more of their time doing exploratory testing


 
Junilu Lacar
Sheriff
Posts: 17644
300
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

Sam Parson wrote:...and not actual unit testing or tdd. He said unit testing and tdd is running tests just to make sure it works.


This is an incomplete understanding of TDD as it relates to unit testing. TDD is a design technique, not a testing technique. It uses tests to drive how you think about design and refactoring helps you get to better designs when the tests show you something that isn't quite right. When properly done, unit tests show you examples of how your class is used and interacts with other classes to get a job done. All this is squarely in the domain of responsibility of the developer. Modern agile teams work together with "QA" or test-focused engineers. There should be no "trying to break your code" kind of attitudes but rather something more like "let's see what else we might have missed" type relationships on good teams.
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Sam Parson wrote:To answer the first question It would give a runtime index out of bounds error ...



Which would then percolate up until it reached a public method, which you would be testing, and which one of your test cases would catch it. But I see something about random numbers there, so conceivably it would be an error which couldn't be reproduced reliably. That's a whole separate can of worms for testing, though.


The calculations made are done with factorial numbers, conditional boundaries, and random selections. The issue here is there are easily over a billion combination tests (int rndNumber, int hpBaseline, int hpValue) I would have to write for the public method, to test every usable outcome of that private method (or go through them 1 by 1, to figure out which ones produce same resulted outcomes of "int hpDifference = rndNumber + ((int)( 100 * (hpBaseline / (double)hpValue)) - 100);"). This is why I would think it would be better to just test that private method directly.

Junilu Lacar wrote:

Sam Parson wrote:My mentor/friend was saying this would be more for QA testing and not actual unit testing or tdd. He said unit testing and tdd is running tests just to make sure it works. But running tests outside the boundary scope is more the job of QA testers who should try and break your program. I'd like to think I can automate this somehow, but if pressured for time, managing test methods at the end of every class before deployment would probably cause a headache, and I would leave it to the QA people.


This is a bit odd. If you are doing TDD, leaving boundary conditions to someone else seems like a cop out. Leaving boundary conditions to QA folks is a very traditional style development attitude. Look up CORRECT testing of boundary conditions.

QA folks should really spend more of their time doing exploratory testing



So this is where he and I had a bit of a disagreement on. He said I should test the min, max, and middle... For example:
In a range of integers 1 through 10...
His tests would be -> test 1, test 5, and test 10.
My tests would be -> test -2147483648, test -2147483647, test -1, test 0, test 1, test 2, test 5, test 9, test 10, test 11, test 12, test 2147483646, and test 2147483647
...
Now should I be expected to write tests for every number available outside the boundaries? What if number 1715385483 fails? How would I know it would be a test that fails without writing a test for every single number outside the boundary (also imagine how long these tests would take to execute all at once)? This is something I would hope QA would catch before release to customers.

Junilu Lacar wrote:

Sam Parson wrote:...and not actual unit testing or tdd. He said unit testing and tdd is running tests just to make sure it works.


This is an incomplete understanding of TDD as it relates to unit testing. TDD is a design technique, not a testing technique. It uses tests to drive how you think about design and refactoring helps you get to better designs when the tests show you something that isn't quite right. When properly done, unit tests show you examples of how your class is used and interacts with other classes to get a job done. All this is squarely in the domain of responsibility of the developer. Modern agile teams work together with "QA" or test-focused engineers. There should be no "trying to break your code" kind of attitudes but rather something more like "let's see what else we might have missed" type relationships on good teams.


I would have to disagree with TDD not being a testing technique. I recommend watching this video by Robert C. Martin -> https://www.youtube.com/watch?v=qkblc5WRn-U

In my reply to "There should be no "trying to break your code" kind of attitudes but rather something more like "let's see what else we might have missed" type relationships on good teams."...
So, I have been on One good team (as a QA guy), and the rest were highly toxic teams (somewhere between QA and a Software Developer). I realize attitude is one of the many human flaws that affect quality performance.  So perhaps I'm not using the right Political Correctness term (because they both do mean the same thing in this context of testing for bugs). It's just the term I got from this video -> https://www.youtube.com/watch?v=p0O1VVqRSK0 (beings at 24:00, talking about the manual testing process between QA and devs), (Starts talking about how Most QA tests should be automated at 21:00)

Also, another good video talking about what is actually happening now between devs and QA -> https://www.youtube.com/watch?v=p0O1VVqRSK0 (begin at 32:40 on his talk about the relationship between devs and QA).

I hold myself to extreme standards, because I remember how clean and simple (and actually workable) software used to be. There were very few bugs. I've watched technology grow over the decades, and it seems like it just keep getting worse. For example... Windows 7 vs Windows 10 (I feel that is all that needs to be said about that). I just really want to develop good test habits for myself, so when my name is on the code I put out, it will not be something I would be ashamed of.
 
Junilu Lacar
Sheriff
Posts: 17644
300
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
Thank you for posting that link to Uncle Bob's talk. Nowhere in that talk does he say that TDD is a testing technique. In fact, much of what he says supports the argument that TDD is a design technique.

At 12:20, he says "When you are following the three laws of TDD, what you will produce in the unit tests are the code examples of the entire system."
and a little later, "That's what unit tests are: They are little snippets of code that explain how the system works. And because you are doing TDD there is a snippet in there that explains how every part of the system works"
In other words, if you do TDD properly the test code becomes a complete detailed design specification of the code that you wrote. See Jack Reeves essays on Code is Design

At 15:30, he says "Inevitably, however, you will come to the code that's hard to test. It's hard to test beicause you did not design it to be testable."
At 18:14, he says "You have to design all your functions to be easy to test because you're writing the tests first."

He also talks about bad code and messy code. He talks about cleaning up the messes we make. One thing that the three laws don't talk about is the very important, and arguably THE most important step of TDD: Refactor. Refactoring is defined as "Improving the DESIGN of existing code."

So,
Writing the test before writing production code only makes sense if you're writing test code so you can express an initial DESIGN and try it out.
Writing only enough production code to make a failing test pass only makes sense if you are doing incremental and emergent DESIGN.
Refactoring after you get your tests to pass is to clean up any mess that you made and make your DESIGN better.

Therefore, TDD is primarily a DESIGN technique that uses tests as the motivation and impetus for thinking about, experimenting with, and improving your DESIGN.
 
Junilu Lacar
Sheriff
Posts: 17644
300
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

Sam Parson wrote:
Also, another good video talking about what is actually happening now between devs and QA -> https://www.youtube.com/watch?v=p0O1VVqRSK0 (begin at 32:40 on his talk about the relationship between devs and QA).


It's good that you're watching all these Uncle Bob videos because, in fact, these are pretty much what I base my coaching on. FYI, my day job is as an Agile technical coach and I teach folks things like TDD and refactoring and pair programming.  The things I teach are based largely on Uncle Bob's writings and talks and those of people like him. They are also based on my own experience with development teams where we practiced all these things that Uncle Bob talks about.

I was almost going to write "QA should expect to find nothing" in my original responses but I thought that might be too radical an idea for you, that's why I said the attitude/relationship should be more cooperative, with test-focused engineers working closely with development engineers so that both sides understand the kind of rigors the code and design would be put through during downstream testing activities like when you do integration, performance/load, and penetration testing.

OP wrote:what is actually happening now between devs and QA


In my experience as a long-time developer, tech lead, and coach, the majority of teams still don't have this kind of relationship between QA and dev. It took a while for the team I worked with in my last job to get to "QA should expect to find nothing" because that only happens when teams are working together to effectively squash all existing bugs, refactor their designs, and start producing clean code and clean designs developed through techniques like TDD. Once the team gets to where they are doing TDD effectively, then the QA guys can reasonably and confidently expect to find nothing. That's when their reason to exist boils down to primarily doing manual exploratory testing, to test things that can't or don't make sense to be tested through automated means.
 
Junilu Lacar
Sheriff
Posts: 17644
300
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

Sam Parson wrote:
So this is where he and I had a bit of a disagreement on. He said I should test the min, max, and middle... For example:
In a range of integers 1 through 10...
His tests would be -> test 1, test 5, and test 10.
My tests would be -> test -2147483648, test -2147483647, test -1, test 0, test 1, test 2, test 5, test 9, test 10, test 11, test 12, test 2147483646, and test 2147483647
...
Now should I be expected to write tests for every number available outside the boundaries? What if number 1715385483 fails? How would I know it would be a test that fails without writing a test for every single number outside the boundary (also imagine how long these tests would take to execute all at once)? This is something I would hope QA would catch before release to customers.


This is where doing TDD as a pair or as a mob creates synergy. Again, you'd be talking about the design, in this case, the design of the tests themselves. What conditions are you testing will all those different cases? Do each of those cases represent a unique set of conditions that could result in incorrect behavior in the program or are some of them redundant? Your test cases should not be arbitrary "just in case" deals, they should have a specific goal and focus and they should reflect your understanding of the program and the implementation. Redundant tests reflect a lack of understanding of the exact behavior of your code and that's not only wasteful, it's also dangerous.

So, when you ask "should I write tests for every single number outside the boundary?" you're either being snide or you don't fully understand what the code is doing and what its limitations are, or a combination of both.
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sam Parson wrote:Now should I be expected to write tests for every number available outside the boundaries? What if number 1715385483 fails?



Well, if you've got a chaotic relationship between the inputs and outputs then that could conceivably happen. But in the majority of applications that people write aren't like that -- if the customer pays $10.30 for 93 grams of zinc tubing and $10.75 for 98 grams, you would not expect the price of 96 grams to be $8,355.17. And so you wouldn't consider testing that. (At least I wouldn't.)

 
Junilu Lacar
Sheriff
Posts: 17644
300
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

Sam Parson wrote: ...develop good test habits for myself, so when my name is on the code I put out, it will not be something I would be ashamed of.


This is a great attitude to have and one that I take very seriously. I have done TDD for several years now. In fact, I'm arguably the most vocal proponent for the practice around here. I'm also very much about craftsmanship and clean code and TDD is one of the best ways for me to practice craftsmanship and write clean code. It's not the testing that gives you all that though, it's everything about design thinking that testing leads you to do that results in clean code and good designs.
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Junilu Lacar

Thanks for the replies. It all looks good. I do have one question though... What would you consider to be testing techniques if TDD is not one of them?

Also, in reply to the:

Junilu Lacar wrote:So, when you ask "should I write tests for every single number outside the boundary?" you're either being snide or you don't fully understand what the code is doing and what its limitations are, or a combination of both.



I apologize if I came off as being snide (that certainly was not my intention). Sometimes I ask rhetoric questions as I have found this to sometimes be a better method to relay answers when I get people to think about the answer rather than being told the answer.
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also, in addition, I'm trying to come up with a better directory name than "ClassFiles":


I appreciate any ideas on this.
 
Junilu Lacar
Sheriff
Posts: 17644
300
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
Sam, no problem, it wasn't meant to be a reproach or anything like that, I just couldn't find the right word to translate what I wanted to say in my native tongue (a Filipino dialect) which is something like being snide except in a more joking rather sardonic tone. The word we use in my dialect is pilosopo which is based on "philosophical" except it's more smart-alecky. I don't know how to convey it without making it sound bad, which it isn't supposed to be. Anyway, no harm, no foul.

As for the directories, the more commonly used ones are bin and classes
 
Junilu Lacar
Sheriff
Posts: 17644
300
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
Sam,

As far as actual testing techniques, I'd say things like using fakes, mocks, stubs, spies, and things like that are techniques. FIRST and CORRECT unit tests might also be considered as "techniques" although I'm more inclined to see them as guidelines really, as is AAA Arrange-Act-Assert.

Fuzzing is a testing technique
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So making the proper changes broke one of my classes. I can't figure out why it can't see the method...

New Directory Tree:


Both these lines were how it worked before (looking at the directory tree image in the very top post of this OP):


As you can see, it doesn't recognize these methods. Any idea why?
 
Sam Parson
Greenhorn
Posts: 15
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Nevermind, I just needed to remove both those import lines and add the line
 
Junilu Lacar
Sheriff
Posts: 17644
300
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
Sam,

The project structure you're using is very unusual. Most real-world Java projects these days are organized the way Ron showed before and tools like Maven and Gradle expect projects to be organized that way.

I suspect the problems you were having with the structure Ron suggested was an IDE configuration issue. I noticed that your package declarations were test.java.com.example and main.java.com.example -- that's not right. In the IDE, you should configure your project to have test/java and main/java as your content roots. See https://www.jetbrains.com/help/idea/working-with-modules.html#configuring-content-roots

Then in both your application and test classes, your package declarations should just be:

 
Junilu Lacar
Sheriff
Posts: 17644
300
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
Having test cases that directly test private methods in production code is a smell. Private methods usually contain implementation-specific details that may change over time but shouldn't affect the observable behavior of a class. Having tests that depend on implementation-specific details makes your test class more brittle because any test method that depends on an implementation detail is more likely to break if the implementation changes.

It's fine to test code that goes into private methods as you're developing it. If I really want to make sure a particularly complicated piece of implementation code worked correctly, I first test the code as part of the test class itself. Then when I'm confident it works the way it should, I copy it over to the main class.

Here's an example. Let's say I wanted to use a particular search algorithm in the main class but I want to make sure I implemented it correctly. To do this, I would first create a private method in the test class, not the main class.


When this test passes, I copy it to the main class.

Then I continue to test drive any behavior that might use this particular algorithm.

When I implement the bar() method as a public method in Foo, I may decide to have it call the private findMax() method that's already there. Whether or not I choose to do that should not be evident in the bar_does_something() test case. This keeps the test implementation-agnostic and more resilient to changes. I can still be confident that if I do choose to use findMax(), any test failure would not be due to something being wrong in findMax().

When I'm done test-driving the code for all public methods in Foo that use the private findMax() method, I'll either delete it from the FooTest class or check it into source control if I think it might be useful later.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic