Integration Testing w/ Specific Data

Yeah I see!

That does make economical sense, and makes tests easier to find I suppose.

I know from a brief twitter poll I did last week many people seem to keep as fewer assertions as possible in their tests.

I'll write some tests in this fashion and see how it sits with me.

Robert

I think you're right.

Handling database stuff in this manor rather than mocking may well be a much better way of doing things.

Thanks for all you input, really appreciate it!

Robert

So what you are saying is that if you make a change to test #1, which checks for a valid login that breaks the failure. You won’t know about it till you run test #2, is that right?

With my method you see all know conditions and the outcome of the change to both conditions, in the one test.

Coupled with the mxUnit View, I can just run that one test till I am finished, I am not having to worry about running that test and all other test that are related, which just wastes time.

If you are happy with that way, that’s fine. I started out that way and got sick and tired of trying to run the right tests that was dependant on the first or 3rd, till all passed.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Yeah and how many of them actually write TDD, I don’t know too many that do. And when I was learning unit testing I was in a Java shop, well grails actually and these guys where J2EE experts, and they taught me the way I currently work.

Here is a unit test that was written in Java back in 2005, and it is very self-explanatory and is how I was taught to write them eventually.

package tests;

import com.beust.testng.annotations.*;

import org.apache.commons.lang.StringUtils;

public class StringUtilsTest

{

@Test

public void isEmpty()

{

assert StringUtils.isBlank(null);

assert StringUtils.isBlank("");

}

@Test

public void trim()

{

assert “foo”.equals(StringUtils.trim(" foo "));

}

}

Regards,

Andrew Scott

http://www.andyscott.id.au/

Ah im just saying that I have learnt that keeping things simple generally helps.

Treat your tests like you treat your oop code. Single responsibility principle.

When you start testing multiple conditions in one test, it gets more complicated, so i try to avoid it as much as possible.

My tests arent dependant on each other…all im saying is that if you have one test that tests invalid login and valid login at the same, if you refactor your login service, and then run your tests and they break now, what is it communicating? That your valid login test is failing because of the refactor, or your invalid login test is failing because of your refactor?

Its not immediately clear because both conditions are being tested in one test.

I guess in this case null and “” are both empty.
What you are suggesting is testing for valid login and invalid login in the same test, which are complete opposites.

Well I guess it depends on how you run your tests, I prefer let’s use the doLogin for example. I have a file that first will be called whatever the name of the corresponding code will be so if it is handler/security/doLogin then my unit test is unittest/handler/security/doLogin.

I RMB on this file and run the test to get it loaded into mxUnit in Eclipse, I then refactor and develop and run that test only. Not the entire file, just that test. Which means I can see all conditions pass and fail much quicker than running tests that are not relevant to my current area of focus.

With the single test method per condition, as I stated if you break the failure condition while trying to fix the success condition. You are forced to run the entire file of tests to make sure it passes, which actually can add about 400%-900% of wasted time.

The amount of time that it takes to run the test is reduced during my development stage, because I am not doing the following.

  1. Waiting for the entire test file to complete all 75 tests, which in my case can take as much as 30 minutes.

  2. Instead I run one test which can take as little as 2 secs to a minute, make the changes I think is required. Run that one test method again.

In the space of 30 mins, I have written and refactored maybe 150 lines of code. And that is worth more to me than sitting there waiting for non-relevant tests to then finish as well.

This becomes extremely important during TDD because the more time you can give to your development, the better off you are. Like I said I was doing it the way you currently do it too John, but when I was shown a more productive way I have never looked back. And you know that those who write a single method test for each condition, is not too fussed about productivity, or is just plain ignorant that time is money.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Ok cool.

I had similar issues with slow tests at first, which is why i implemented the transaction method in the link above, now I can run my whole test suite really really quickly. 30 mins to run all your tests is really slow.

Also I seperate my unit tests into folders, which i think you do as well, so all my login tests will be in tests/units/login. I can now run mxunit from that folder level only when im working on my login service, so only the tests that relate are being run. Or sometime I just run the one file at a time from mxunit, so I am just running the tests that im focussed on.

Anyway, I think the main thing is that its really good to use unit tests full stop, no matter which way you do it, and its also good to have a discussion like this about it. To see how other people are doing it, I dont think its discussed and promoted enough in the coldfusion community.

Agreed! This has an been a really valuable conversation. Thanks guys.

Robert

Is it, it is a very heavy application. And picked this one part to illustrate my point.

And I focus on the one file, and the one method. Which is what I am saying, in your case you have to run that one file and if you have 75 tests in that file, you have to wait for each one of those tests to run before you know if you have done your job.

In my case I run one test in that file to see if I have done my job, and that is where the productivity can come into it.

Try it next time your developing, using the mxUnit view and compare the entire file run and then the one test in that file. And then take out the fact that I am not running 3 tests in that file to test one functionality test.

Look at the end of the day you are comfortable with the way you work, I am passed that and feel the way I do it is much more productive. Because I am not running 74 other tests to work on one.

Regards,

Andrew Scott

http://www.andyscott.id.au/

And no it is not discussed enough.

Regards,

Andrew Scott

http://www.andyscott.id.au/

As a bit of a compromise, and assuming you’re using MXUnit, you could look at DataProviders.

http://wiki.mxunit.org/display/default/Data+driven+testing+with+MXUnit+dataproviders

I’ve found myself using them more and more in the past few months and they’re a good way of finding balance between having lots of individual tests and “god” tests.

Cheers,
James

Yeah I don’t use that as it won’t work in cfscript, but it is another solution.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Thanks James, certainly looks useful!

@Andrew - it looks as if it does work in script, just uses annotations:

/**
* @mxunit:dataprovider myDataProvider
*/

Robert

Cheers you know I never thought of doing it like that, cheers handy to know.

Regards,

Andrew Scott

http://www.andyscott.id.au/

I can see what your saying, but I dont have 75 tests in one file, and
my tests run so fast that running all the tests in one file takes
about 2 secs. If theres one of two tests in the file which arent
directly related to what im refactoring it isnt such an issue. Also,
its good to ensure that your refactoring isnt effecting other
unexpected areas of your code, so I guess many would argue that you
should be running the whole test-suite as much as possible to prevent
this.

Its fair that you have your own method of working, but its good to
accept other methods as being just as good for different reasons.