Archive for the ‘Agile’ Category.

Java Spring MVC 3.2.0 UnitTests

I had a bit of a fight today, I wanted to UnitTest some Java Spring MVC code that I’m using for a demo application. But after a lot of Googling, StackOverflow and hitting different documentation of Spring 3.0, 3.1 and 3.2 I finally came to an acceptable solution. Mind you a minimal sample to test MVC controller without having to go crazy with decelerations, attributes, injections and so on and so forth, you catch my drift. There has been a lot of movement from those three versions I mentioned and finally the spring UnitTesting lib has now been folded into Spring itself, this is good news.
Btw, I found the answer in the Spring MVC showcase on GitHub, where else ?

So lets take a look at what you need, bare minimum just the way I like it.

Using Maven, you will need the ref in your POM file

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.2.0.RELEASE</version>
            <scope>test</scope>
        </dependency>

The controller class I’m using comes pretty much directly from creating a new MVC Spring project from Eclipse.

package us.kristjansson.springTest;
//
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
//
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */

@Controller
public class CxHomeController
{
       
        private static final Logger logger = LoggerFactory.getLogger(CxHomeController.class);
       
        /**
         * Simply selects the home view to render by returning its name.
        */

        @RequestMapping(value = “/”, method = RequestMethod.GET)
        public String home(Locale locale, Model model)
        {
                logger.info(“Welcome home! The client locale is {}.”, locale);
                //
                Date date = new Date();
                DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
                String formattedDate = dateFormat.format(date);
                model.addAttribute(“serverTime”, formattedDate );
               
                return “home”;
        }
       
}

Then lets look at the Test itself.

//
package us.kristjansson.springTest;
//
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import org.springframework.test.web.servlet.MockMvc;
//
import org.junit.Before;
import org.junit.Test;

public class TxHomeController
{
         //
         private static final Logger logger = LoggerFactory.getLogger(TxSample.class);
         private MockMvc mockMvc;

         @Before
         public void setup() throws Exception
         {
                 logger.info( “Setup CxHomeController” );
                 this.mockMvc = standaloneSetup(new CxHomeController()).build();
         }

         @Test
         public void TestController() throws Exception
         {

                 //
                 logger.info( “testing CxHomeController” );
                
                 // The CxHomeController’s view is "home" without content
                 this.mockMvc.perform(
                           get(“/”))
                                 .andExpect(status().isOk())
                                 .andExpect(content().string(“”))
                                 .andExpect(view().name(“home”) 
                                 );

         }
       
}

Maven Sonar plugin for your Java project

I needed to add Sonar reporting to a small Java project that uses Maven for the build. There is a Maven Sonar plugin available for this task here.

First add sonar properties file ( sonar-project.properties ) to your java project, put it in root.

# info
sonar.projectKey=javaTest
sonar.projectVersion=1.0
sonar.projectName=Sample java spring MVC project

# Comma-separated paths to directories with sources (required)
sonar.sources=src

# Language
sonar.language=java

# Encoding of the source files
sonar.sourceEncoding=UTF-8

Make Maven aware of the Sonar location etc, add that to the Maven settings \maven\conf\settings.xml

Something like this

<profile>
       <id>sonar</id>
       <activation>
          <activeByDefault>true</activeByDefault>
       </activation>
       <properties>
          <!– SERVER ON A REMOTE HOST –>
          <sonar.host.url>http://remotebox.com:9000</sonar.host.url>
          <sonar.jdbc.url>jdbc:h2:tcp://remotebox.com:9092/sonar</sonar.jdbc.url>
       </properties>
    </profile>

For Maven version 3+ add this to the POM file in the build section, else Maven version 2 ( below ).

<plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>sonar-maven-plugin</artifactId>
        <version>2.1</version>
      </plugin>

For Maven 2.

<plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>sonar-maven-plugin</artifactId>
        <version>1.0</version>
     </plugin>

Pass the sonar:sonar goal to the Maven script then kick off a build, the dependencies should be downloaded automatically. The report for your project displays on the Sonar server dashboard.

TeamCity Twitter plugin, part 2

I had to fix an old plugin I made some time back, I did actually post about it here Java Authenticated POST. So why bring it up again, a good question I say. As Twitter changed their authentication sometime late last year ( Nov 2010 ? ). All programs using the old authentication stopped working. I hadn’t had / given myself time to look at the broken plugin. What the TeamCity twitter plugin does it to tweet when the TeamCity server starts and ends builds. If you follow that account you get notified on Twitter without having to open up your email box to see how your builds are doing.
I went googling about the new authentication and found a nice snippet on StackOverflow The snippet uses Twitter4J library to make the task really simple, check them out. The best part is that Twitter4J only needs Java 1.4 to run. That’s great as my TeamCity server only has Java 1.5 and not the newer 1.6, further as an added bonus their core jar is only 280k, that’s all I needed. Below is my code modified from the StackOverflow sample. It works fine if you are only posting to one account. The tokens and keys can be found on your Twitter app page. If you need to post for different users from your application then your code needs to take that into account. If you want the source of the plugin or all 3 plugins I have created, you can run over to GitHub and pick it up. I made it public domain, open source, whatever you want to call it.

import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.conf.*;;

   // Updates the twitter account
   public static void sendTweet( String psText )
   {
           try
           {
                        // Configuration
                        ConfigurationBuilder confbuilder = new ConfigurationBuilder();
                        confbuilder.setOAuthAccessToken(CxGlobal.ACCESS_TOKEN_KEY)
                        .setOAuthAccessTokenSecret(CxGlobal.ACCESS_TOKEN_SECRET)
                        .setOAuthConsumerKey(CxGlobal.CONSUMER_KEY)
                        .setOAuthConsumerSecret(CxGlobal.CONSUMER_SECRET);
                                               
                        // get the interaction object
                        Twitter twitter = new TwitterFactory(confbuilder.build()).getInstance();
                        // send
                        twitter4j.Status status = twitter.updateStatus( psText );
                        //
                        //System.out.println("*** Response=" + status.getText() );
           }
           catch( Exception ex )
           {
               System.out.println( “***ERROR=” + stack2string( ex ));
               LOG.info( “***ERROR=” + stack2string( ex ) );
           }
   }

Edit, the 3 plugins have now been added to the official TeamCity PlugIn page

Selenium browser UnitTesting from TeamCity

I just setup browser testing framework utilizing Selenium from TeamCity project. The usual suspects are involved, Gallio, MBUnit, Nant and even C# Unittests.

The usual scenario when it comes to automating browser testing is that the QA / testers will create some scripts to run a browser against your website. Somehow those tests are usually not maintained very well and often are run by hand. There is not much value in browser testing scripts if you have to run them by hand.

As I needed browser testing on one of the projects I’m on I decided to look into using more of a automated setup to run the browser tests. There seem to be two big players Waitn and Selenium, Selenium lends itself to broader range of testing, naturally we will go with Selenium.

Here is the scenario I want, the tester installs a recorder on his computer, in this case a FireFox plugin. The tester records the tests and runs them in the browser using the plugin tool. Once the tester is happy with the tests the tester checks them into the repository. After check-in tester lets a developer know that there are new or changed tests. The developer takes the script and turns it into C# UnitTest, simply has Selenium convert it to UnitTest code. Then the developer takes and updates or adds the tests that resulted from the scripts and checks it into the repository. The conversion step could be automated in the future once Selenium supports that. The next step is to run it from TeamCity and after it runs you get email with the results.

So let’s take a closer look at what is needed. We need the UnitTest to be able to run against different servers using different browsers. We will pass values from TeamCity to the Nant script that is responsible for compiling and running the tests. This is how your test C# configuration file might look like.

<!– Selenium RC properties–>
    <add key=“SeleniumAddress” value=“localhost” />
    <add key=“SeleniumPort” value=“4444” />
    <add key=“SeleniumSpeed” value=“0” />
   
    <!– Browser targets –>
    <add key=“BrowserType” value=“*firefox” />
    <add key=“BrowserUrl” value=“http://10.9.169.198/” />
    <add key=“BaseUrlPath” value=“IPCA.Dev/” />

Then the base test class will look something like this.

[FixtureSetUp]
        public virtual void TestFixtureSetup()
        {
            // Read from config
            msBrowserType = getConfigSetting(“BrowserType”, msBrowserType );
            msBrowserUrl = getConfigSetting(“BrowserUrl”, msBrowserUrl);
            msBasePath = getConfigSetting(“BaseUrlPath”, msBasePath);
            //
            msSeleniumAddress = getConfigSetting( “SeleniumAddress”, msSeleniumAddress );
            miSeleniumPort = int.Parse(getConfigSetting(“SeleniumPort”, miSeleniumPort.ToString()) );
            msSeleniumSpeed = getConfigSetting( “SeleniumSpeed”, msSeleniumSpeed );
           
           
            // Start up the selenium session, using config values
            selenium = new DefaultSelenium(msSeleniumAddress, miSeleniumPort, msBrowserType, msBrowserUrl);
            selenium.Start();
            // Clean errors
            verificationErrors = new StringBuilder();

            // sets the speed of execution of GUI commands
            selenium.SetSpeed(msSeleniumSpeed);
        }

        [TearDown]
        public void TeardownTest()
        {
            try
            {
                selenium.Stop();
            }
            catch (Exception)
            {
                // Ignore errors if unable to close the browser
            }
            Assert.AreEqual(“”, verificationErrors.ToString());
        }

And a sample Selenium C# Unittest

//
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
//
using Gallio.Framework.Assertions;
using MbUnit.Framework;
//
using Selenium;

namespace SeleniumTests
{
    [TestFixture]
    public class LoginPage : WebTestBase
    {

        [Test]
        public void TheLoginPageTest()
        {
            selenium.Open( this.msBasePath + “TestLogin.aspx”);
            selenium.Click(“lbAdmin”);
            selenium.WaitForPageToLoad(“50000”);
            selenium.Click(“loginLink”);
            selenium.WaitForPageToLoad(“50000”);
            try
            {
                Assert.IsTrue(selenium.IsTextPresent(“my responsibilities regarding permissible access”));
            }
            catch (AssertionException e)
            {
                verificationErrors.Append(e.Message);
            }
            selenium.Click(“ctl00_pageContent_btnSubmit”);
            selenium.WaitForPageToLoad(“50000”);
            try
            {
                Assert.IsTrue(selenium.IsTextPresent(“Total Unassigned Web”));
            }
            catch (AssertionException e)
            {
                verificationErrors.Append(e.Message);
            }
        }
    }
}

After the Nant script compiles the tests and is getting ready to run the UnitTests it needs to startup the Selenium engine. Make sure to spawn in order for the Selenium engine to exist on another thread than your tests.

<property name=“SeleniumExec” value=“java” />
  <property name=“SeleniumPath” value=“C:\apps\selenium\selenium-server-1.0.3\” />
  <property name=”SeleniumParams” value=”-jar ${SeleniumPath}selenium-server.jar” />

    <!– Start selenium –>
    <exec   program=”${SeleniumExec}
      commandline=”
${SeleniumParams}” workingdir=”${path.base}${WebTest}
      spawn=”
true” failonerror=”true” verbose=”true
       />

    <!– Give it a sec to load –>
    <sleep milliseconds=”3000” />

In order to run the tests using different browsers, change the configuration file of the tests before run.

<!– Run tests in Firefox browser –>
    <xmlpoke
        file=“${path.base.test}${assembly.test.config}”
        xpath=“/configuration/appSettings/add[@key=’BrowserType’]/@value”
        value=“*firefox”
        verbose=“true”/>

    <call target=“runTests” />

<target name=“runTests”
    description=“runs tests using Gallio.” >

   
    <echo message=“*** Start runTests: “/>

      <gallio
        result-property=“exitCode”
        failonerror=“false”
        report-types=“Html;Xml”
        report-directory=“${artifacts}”
        report-name-format=“gallioresults”
        show-reports=“false”
        application-base-directory=“${path.base.test}”
            >

          <!– Specify the tests assemblies  –>
          <files>
            <include name=“${path.base.test}${assembly.test}”/>
          </files>
        </gallio>

        <!–
            Set error for email injector to pick it up and GlobalFailBuildMessage for
            the end target to fail the build after cleanup
          –>

        <if test=“${int::parse(exitCode)!=0}”>
          <property name=“GlobalFailBuildMessage” value=“*** One or more tests failed. Please check the log for more details” dynamic=“true” />
          <echo message=“EmailInjectMsg=${GlobalFailBuildMessage}” />
        </if>

    <echo message=“*** End runTests: “/>
  </target>

And after the run of the Unittests Selenium needs to be shut down

<!– Stop Selenium server –>
      <get  src=“http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer”
        dest=“shutdown.txt”  failonerror=“false”
      />

As I had a need to setup different configurations in TeamCity to run against different locations on the webserver I used a couple of Nant variables that are passed on the command line from TeamCity, like you normally would do when running Nant script -D:BaseUrlPath=/Test/ etc.

<echo message=“*** Location variables passed from TeamCity”/>
    <echo message=“*** BrowserUrl=${BrowserUrl} “/>
    <echo message=“*** BaseUrlPath=${BaseUrlPath} “/>

Of course you get the Gallio UnitTest report as well

gallio_report

With this setup once we deploy to a server we can run all the browser tests on it using different browsers with one click of a button from TeamCity.

#swBoulder 2010 – Startup Weekend

What does the #swBoulder hashtag stand for you may ask. sw stands for Startup Weekend the one I attended last weekend was held in Boulder they are held all over the country and in other countries well. Andrew Hyde is the founder of Startup Weekend and so much more, check him out.

Let me give you first a little bit of information what it is all about. Simply work in startup mode for a weekend on a project of your choice and see what you can produce with your team. It’s a event geared towards technology / software, however you don’t have to be developer. Most of the teams are made up of people with different backgrounds marketing, sales, business, developers and other skills as well. Everybody brings something to the table, it doesn’t matter what it is. If you like to contribute to a project in a startup settings this event is for you. Don’t worry about what you can do or what you can not do, there is room for everybody and everybody contributes. Some of the people working on the project do not have time to stay for the whole weekend that is fine as well, you contribute what you can. Of course it’s best to give the lead that information up front in order for the lead to know how you can be used as a resource over the course of the weekend.

And here is how it went down for me. The event was held at CU Leeds School of Business, people started gathering in around 17:00 on Friday. There was pizza and beer, the usual menu that most people can deal with. To kick it off Cameron Burgess and then Rich Grote ( SnapImpact ) had entertaining and informative talks to set the tone for the event.
Next up those who had an idea that they wanted to pitch got the stage for 5 minutes each. I did have an idea of my own but decided not to push it as the crowd of 40-50 people ended up with 13 ideas presented, there was plenty to choose from. Next the crowd voted on the ideas, which ones were to be worked on over the weekend, 8 of those were chosen. At this point you had to choose which idea you wanted to work on. There were two ideas I liked and I talked to both presenters then chose lloyddobllers idea from there. As the groups start to form the people in the group start figuring out plan of attack and take ownership of different aspects of what needs to be done. This is your opportunity to work on something that you feel is exciting or new. At this point our group broke up and we started poking at what needed to be done each in our own corners, I had an Avalanche game to watch and did not get much done rest of the night. We figured we would show up around 9 on Saturday morning.

Saturday morning we showed up early ready to work going as fast as we could. As in a normal startup, time is of essence and things move quickly, just keep going. For lunch Ayush Agarwal came by and had a talk about Startup Weekend and gave some tips about what the judges are looking for which benefited us greatly and then took questions. Then back to work, before you know it it’s getting close to midnight. We actually made the mistake of forgetting to have dinner and were running pretty low when we headed home for the night. Home to get some food and recharge the batteries.

Sunday morning after some hours of sleep we showed up again ready to rock it for the rest of the day. We really wanted to ship a product before the end of the day. It was recommended to us to ship on Saturday night, but how could we, we had plenty of hours to work in more features on Sunday. Along with a prototype of the application we put together a business plan and a slide presentation. Even a promotional video was made along the way. As expected it came down to the wire on the development side, we wanted certain features and finished up with 20 minutes to spare. we demoed the website live on our own domain during our presentation, no crashes… 🙂

During the presentations, the judges got busy both with questions and forming their opinions of the projects. 6 out of 8 projects made it to the finish line, props goes to one of the teams which lost all but two of their people through the course of the weekend but still presented a viable idea, way to stick with it. Apparently our project kicked ass and was chosen the best one by the judges. That was the icing on the cake for our hard work through the weekend, but regardless I think we would have been very proud of what produced regardless of what place we ended up at. Not only was the idea business viable but we managed to ship, have a good business plan, presentation, live demo of the product and exit strategy we even signed up couple of partners along the way.

In my case I had never done Twitter OAuth authentication and offered to work on that, now I know how that works. As we decided to use .net to code, I found code to reuse from .Net solution by Shannon Whitley thanks.

Here are pictures from the event from Lev Mazin from AskYourTrgtMrkt which was on hand allowing the teams to market research their ideas as they formed.

John Sheehan was also there from Twillio they sponsored the event. John happened to be helping out on my team and was a great asset.

This was my first Startup Weekend and I didn’t really know what to expect, sometimes as with this event I did little research by choice as I wanted to see how I would react to it myself. For me it was a breath of fresh air. Working hard for a weekend and to see the result at the end of it was a blast. Then coming back to work on Monday feeling energized ! It brought back some good memories from startups I had in the past. It is really a startup mode for a weekend very much like in the real world just more compact.

TeamCity replacing build agent

We have the Professional version of TeamCity at work which allows 3 build agents / machines and 20 users. It’s big enough for our efforts. We just put an old build machine to bed and a new one is coming online. However I could not find how to remove agent from the TeamCity interface. First I uninstalled the agent on the old build machine, but the profile was still on the server. I ended up going into the Oracle TeamCity database and deleting the profile from the AGENTS table. After that I was able to add the new build agent in the TeamCity server console.