Developer testing of GUIs, like those written in Swing for example, have always been a challenge. Regardless of how a particular GUI is coded, ascertaining testing plug-in points and determining how to structure a particular test case presents barriers that often force one to postpone testing until a more manual effort can be conducted. As I mentioned a few months ago, there are a number of frameworks available that facilitate testing various GUI frameworks; however, of late, I have found that one particular framework for testing Java GUIs stands out– testng-abbot.
While the framework is fairly new and lacking of a lot of documentation, the features found in the latest version make testing a GUI (either AWT or Swing) quite easy. For example, testing the following scenario takes one test case and an associated fixture. Below is a sample Swing GUI that excepts two parameters representing a Widget’s name and weight.
In a sunny day scenario, if a user enters a valid weight like that shown below, a successful creation message is shown.
Pressing the Create button yields the following snap shot.
If the weight isn’t a valid integer the GUI will deny the submission. Otherwise, the submission works and a successful creation message is displayed.
Testing this three step scenario pragmatically isn’t as hard as it seems. First, a valid instance of the GUI must be created.
@BeforeMethod
private void init() {
fixture = new AbbotFixture();
fixture.showWindow(new WidgetFrame(),
new Dimension(300, 200), true);
}
Next, both text fields must be populated with valid data. This is easily achieved with testng-abbot through fixture helpers. In my case, I use two TextComponentFixture objects.
TextComponentFixture text1 =
new TextComponentFixture(this.fixture, "widgetName");
text1.enterText("Test Name");
TextComponentFixture text2 =
new TextComponentFixture(this.fixture, "widgetWeight");
text2.enterText("1245");
Lastly, the Create button must be hit, which is also done with the help of testng-abbot fixtures– in this case, the ButtonFixture object.
ButtonFixture bfix =
new ButtonFixture(this.fixture, "widgetCreate");
bfix.click();
Now all that’s left is to verify that a successful creation message is displayed, which involves getting a handle the a JLabel object and verifying a particular String is present.
LabelFixture fix =
new LabelFixture(this.fixture, "statusLabel");
fix.shouldHaveThisText("Widget weight isn't valid");
As you can infer, the shouldHaveThisText method acts as a logical assert and verifies if the particular text is present– if it’s not, then a failure event is triggered.
Putting it all together in with TestNG yields the following simple test case:
public class WidgetFrameTest {
private AbbotFixture fixture;
@BeforeMethod
private void init() {
fixture = new AbbotFixture();
fixture.showWindow(new WidgetFrame(),
new Dimension(300, 200), true);
}
@Test
public void assertSuccess() {
TextComponentFixture text1 =
new TextComponentFixture(this.fixture, "widgetName");
text1.enterText("Test Name");
TextComponentFixture text2 =
new TextComponentFixture(this.fixture, "widgetWeight");
text2.enterText("XTT");
ButtonFixture bfix = new ButtonFixture(this.fixture, "widgetCreate");
bfix.click();
LabelFixture fix = new LabelFixture(this.fixture, "statusLabel");
fix.shouldHaveThisText("Widget successfully created");
}
@AfterMethod
public void tearDown() {
fixture.cleanUp();
}
}
Developer testing of GUIs is by no means a walk in the park; however, with frameworks like testng-abbot, the job is quickly becoming much much easier. What are you waiting for? Start testing those GUIs today!
2007 was kicked off with two independent security researchers, Kevin Finisterre and his accomplice who goes by the pseudonym LMH, publishing details of a flood of security vulnerabilities in Apple’s products.
Known as the “Month of Apple Bugs” and modeled after July’s “Month of the Browser Bugs” and November’s “Month of Kernel Bugs”, the project discloses a new security hole each day in January in Apple’s OS X operating system and the applications that run on top of it.
Some experts and users have questioned the purpose of these projects, debating whether these Month of ‘X’ Bugs are helping security or hurting it. Finisterre and LMH argue that:
Flaws that are publicly disclosed will get fixed quickly.
InformationWeek editor, Larry Greenemeier, explored security researchers’ practices at length, exposing the risks they create but ultimately concluding it’s a necessary price to pay for good software. In the long run, this kind of activity will keep Apple on its toes and will help improve its quality assurance.
The lesson is not that software has bugs. Rather, the point to be taken by developers is that defects removed during the development process won’t come back and haunt the team later — when discovered during regular use or by the researchers dedicated to making software safer.
FxCop is an easy to use static analysis tool, which scans .NET assemblies for violations to pre-defined rules (like naming conventions, security, etc)– while it is now bundled with VSTS, there are still plenty of NAnt-loving shops out there. If your .NET project uses NAnt as a build system and you’re looking for a quick mechanism to objectively look at your code base, then follow these four easy steps for FxCop-NAnt nirvana.
First, you must download NAntContrib, which is a series of tasks not yet included in the core NAnt distribution. Inside this .dll are a series of tasks including fxcop, which of course, runs FxCop (assuming FxCopCmd.exe is in your PATH). The NAntContrib project, by the way, has a host of tasks for working with various CM systems like Perforce, Subversion, and ClearCase to name a few.
Next, download FxCop, install it, and ensure that FxCopCmd.exe is in your PATH. Installing FxCop provides a rather nice GUI that can be run outside of a particular build system too. For example, below is an example of the FxCop application’s results when run against a particular .dll.
Now that you’ve downloaded both NAntContrib and FxCop, the next step is to add a new target to your NAnt build. There are a host of options associated with the fxcop task, however, by far the easiest (and most flexible) is something like this:
Note that this task depends on a binary being in place, hence the depends clause specifies that build be run first. Also note that I’ve specified that FxCop output its results to an XML file, which I can now run my own XSL or one of the included style sheets in the FxCop distribution.
Now that everything is in place, the last step for achieving FxCop-NAnt nirvana is to run it, of course!
Oh my goodness. Paul, look at that code.
It’s so big. *scoff* It looks like
one of those Fortran guys wrote it
But, y’know, who understands those Fortran guys? *scoff*
They only write that stuff because
it looks like job security, ‘kay?
I mean, that method, it’s just so big. *scoff* I can’t believe it’s so complex, it’s just out there
I mean, it’s gross. Look!
It’s just so…legacy
[Sir Refactor-a-Lot]
I like refactoring and I can not lie
You other coders can’t deny
That when a method uses too much space
And its complexity is staring you in the face
You get stung
Wanna extract that stuff
Cuz you know testin’s gonna be tough
Deep in the logic it’s glaring
I’m hooked and I can’t stop staring
Oh, man I wanna get fixn’
And make that logic smaller
My metrics tried to warn me
But that mess its got
Exploited that code’s frailty
Ooh, extract method isolates that logic
and makes testin’ easy
And refactoring is so groovy
Many thanks to Sir Mix-A-Lot for such an amusing song (and Sir Trevor Raps-A-Lot for additional rhymes)– don’t forget to read the original lyrics.
If you need a great source of problem-solving techniques and tips, best practices and up-to-date product information, check out BZ Media’s Web Seminars. Hosted by SD Times and Software Test & Performance, these seminars offer real-time solutions to your software development problems.
You already know that it’s better, faster and cheaper to fix bugs early in your application development cycles. But the last thing
you need is more work in your busy day. Enter Continuous Integrated Testing (CIT), an approach that combines development and testing practices and tools to let you test while you build, increasing quality and saving you time.
Learn concrete techniques for optimizing the QA and testing processes by keeping testing activities aligned with business-facing and performance-oriented requirements.
Don’t forget to visit the seminars archive to check out past presentations!
Regardless if you chose one of the profiled tools or other Eclipse plugins, incorporating them into your work environment will contribute to real-time visual feedback on the state of the quality of your code so that you may prevent problems early in the development life cycle.
Because JUnit 4’s testing model has fundamentally changed due to the introduction of Java 5 annotations, many people have found that the extensive framework of runners, like Ant’s venerable junit task, don’t work.
For example, running the following JUnit 4 test in Ant (pre 1.7) will yield some interesting results.
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class SimpleTest {
@Test
public void verifySimpleAssert(){
assertEquals("simple test", "simple test");
}
}
Using the junit task in Ant yields the following errors:
[junit] Running test.com.acme.SimpleTest
[junit] Tests run: 1, Failures: 1, Errors: 0, Time elapsed: 0.047 sec
[junit] Testsuite: test.com.acme.SimpleTest
[junit] Tests run: 1, Failures: 1, Errors: 0, Time elapsed: 0.047 sec
[junit] Testcase: warning took 0.016 sec
[junit] FAILED
[junit] No tests found in test.com.acme.SimpleTest
[junit] junit.framework.AssertionFailedError: No tests found in
test.com.acme.SimpleTest
[junit] Test test.com.acme.SimpleTest FAILED
In order to have pre 1.7 versions of Ant run your JUnit 4 tests, you must retro fit the test case with a suite method that returns an instance of JUnit4TestAdapter like so:
public static junit.framework.Test suite(){
return new JUnit4TestAdapter(SimpleTest.class);
}
You must fully qualify the return type of Test in this instance because of the similarly named @Test annotation. Accordingly, once this suite method is in place, Ant will happily run JUnit 4 tests.
The newest version of JUnit does not contain a category annotation, like its rival TestNG or its distant cousin NUnit; however, this doesn’t mean you can’t easily categorize your tests. Much like pre-JUnit 4, the solution involves the use of suites; however, as anyone who is actually using JUnit 4 knows, suites, as we used to them, are history– they’ve been replaced with annotations.
Briefly, in JUnit 4, suites have been replaced by two annotations: @RunWith and @SuiteClasses. The @RunWith annotation requires it be set to the Suite class and then the @SuiteClasses annotation accepts a list of class to be run. It is this annotation that facilitates test categorization– for example, to run all unit tests, you would list them all as follows:
@RunWith(Suite.class)
@SuiteClasses({AccountEqualsTest.class, UserTest.class, CalcTest.class})
public class AllUnitTests {
}
Likewise, for component or system tests , you would create similar classes using the @SuiteClasses annotation. As you can see, traditional suite classes are gone in JUnit 4, but the same strategy for test categorization is essentially there– group like tests via suites.
I avoid spending too much time in the philosophy of effective software development, but I felt inspired after reading some interesting threads recently on whether it’s tools, process or something magical that is the difference between a successful and a failed software development project. I find it somewhat amusing when some developers think that the latest programming language or methodology will not only enable us to write flawless code, but let us live in peace and harmony as well. Let me give you a hint: It will NOT!
I am reminded of Coach John Wooden who led the UCLA Bruins to 10 NCAA championships. Coach Wooden focused on fundamentals. Some players want to focus on making a slam dunk or draining a three from 25 feet. However, Wooden’s philosophy was that fundamentals such as free throws, layups, and jump shots were most important. His players would consistently practice layups and free throws until it became second nature (a “non-event”). This is because it was Wooden’s philosophy that what mattered most was executing these “fundamentals” when it counted — such as the last few seconds of a game.
There are similar fundamentals in software development. You won’t get too many people arguing whether the following are effective practices when developing software:
Performing code and design reviews
Writing developer tests
Building software on a separate machine
Is this new information? Hardly. You can look back to articles in the 1960s advocating some of these, or similar, practices. Yet, how many teams have a Daily Build or Continuous Integration, right now? The answer is less than 30%! And, 30% of teams don’t use a version control tool. How many teams consistently perform code/design reviews or write developer tests? It’s my belief that there are some that don’t want to hear the obvious. We want to believe the next “big thing”, be it a programming language or a process with a catchy name, will solve all our problems.
It’s the new year and many, including yours truly, are determined to get into better shape. However, it seems that some don’t want to hear the obvious: You need to consume less calories and move your body more. I’m probably one of the few that hasn’t written a book on the latest health fad, nor am I a medical doctor, but I don’t think I’m too far off. For some, they’d rather ask the question: “How can I get in better shape and still be lazy?”. Some in the software development community are asking a similar question when it comes to improving project success.