Sunday, April 17, 2011

Email Testing with Selenium

If you web application is sending some emails and if you have to test writing code that opens email client (gmail or yahoo) and then check the mails is tedious and also not reliable. The best thing you can do for this is you can have your own SMTP server, that sends the mail for you and stores any system generated mail, rather than sending to actual user for your testing. The best SMTP server I came across is Dumbster.

Now let's see how to use this
Dumster.java
public class Dumbster{
  private SimpleSmtpServer server;

     public Dumbster() {       
       if(server == null)
        server = SimpleSmtpServer.start(25);
     }

     public int howManyMainsSent() {
         int noOfMailsSent = server.getReceivedEmailSize();
         server.stop();          
         return noOfMailsSent;
     }
  
       /**
      * Use only when you are sure only 1 email has been generated
      * @return Subject of the first email
      */
    public String getEmailSubject() {
         Iterator mailIterator = server.getReceivedEmail();
         SmtpMessage email = (SmtpMessage)mailIterator.next();
         return email.getHeaderValue("Subject");
     }
  
     /**
      * Use when more then 1 email has been generated
      * @param count If more than one mails are being generated, Index of the mail
      * @return Subject of the requested email
      */
     public String getEmailSubject(int count) {
          Iterator mailIterator = server.getReceivedEmail();
          SmtpMessage email = null;
          for(int i=1; i<=count; i++){
            email = (SmtpMessage)mailIterator.next();
          }
          return email.getHeaderValue("Subject");
      }
}

Now to use Test the mail you just need to create the server of this class just before you mails shoots and then you need to call the particular function you want.

Tuesday, April 12, 2011

Selenium Grid with JUnit

I just tried my hands on Selenium Grid few days back as our tests were taking too much time to execute, almost 5 hours if we run all and so we thought to use Selenium Grid to cut down the time.  I downloaded the Selenium Gid, run the demo and it all went well until I come to know that your framework should also support parallel execution if you want to run multiple test parallel using Grid. And the problem was JUnit doesn't provided parallel execution. One more reason why you should use TestNG...

There is solution where you can write your own class to parallelize the JUnit testcases  or better download from the Internet. There are so many available. But I found the another and bit easy way.

You can use the ANT parallel task to achieve this parallelism. Following is the demo which shows how to execute testcases parallel with Selenium Grid and JUnit.
Download the demo
  1. Download the selenium gird from here and extract it into some folder
  2. Now navigate to extracted folder through command prompt and type following command
    ant launch-hub
    This will launch the hub on port 4444, this is the port where your selenium tests need to connect.
  3. Now you need to launch the remote control.type the following command on command prompt
    ant launch-remote-control
    This will launch the remote control on port 5555. 
  4. Now we have launched one remote control, we will launch another remote control on port 5556. So one class will execute all it's test on remote control running on 5555 and another class will run it's testcases on remote control running on 5556. Type the following command to launch the remote control on 5556 port.
    ant launch-remote-control -Dport=5556
  5. Now we have two remote control running on the same machine we need to run testcases. 
  6. demo1.java
    import static org.junit.Assert.assertTrue;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import com.thoughtworks.selenium.DefaultSelenium;
    import com.thoughtworks.selenium.Selenium;
    
    /**
     * @author Gaurang
     */
    public class demo1 {
     Selenium selenium;
    
     @Before
     public void setUp() throws Exception {
      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.co.in/");
      selenium.start();
      selenium.setTimeout("6000");
     }
     
     @Test
     public void test_1() throws Exception {
      System.out.println("1");
      selenium.open("/");
      selenium.type("q", "1");
     }
     @Test
     public void test_2() throws Exception {
      System.out.println("2");
      selenium.open("/");
      selenium.type("q", "2");
     }
    
     @After
     public void tearDown() throws Exception {
       selenium.stop();
     }
    }
    
  7. demo2.java
    import static org.junit.Assert.assertTrue;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import com.thoughtworks.selenium.DefaultSelenium;
    import com.thoughtworks.selenium.Selenium;
    
    /**
     * @author Gaurang
     */
    public class demo2 {
     Selenium selenium;
    
     @Before
     public void setUp() throws Exception {
      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.co.in/");
      selenium.start();
      selenium.setTimeout("6000");
     }
     
     @Test
     public void test_3() throws Exception {
      System.out.println("3");
      selenium.open("/");
      selenium.type("q", "3");
     }
     @Test
     public void test_4() throws Exception {
      selenium.open("/");
      selenium.type("q", "4");
     }
      
     @After
     public void tearDown() throws Exception {
       selenium.stop();
     }
    }
    
  8. Build.xml
    <project name="demo" default="run" basedir=".">
     <path id="lib.classpath">
      <fileset dir="lib">
       <include name="*.jar" />
      </fileset>
      <pathelement location="bin" />
     </path>
     
     <target name="run" depends="compile">
      <parallel threadCount='4'>
       <junit printsummary="withOutAndErr" haltonfailure="no">
        <formatter type="xml" usefile="true" />
        <classpath refid="lib.classpath" />
        <batchtest fork="true" todir="results" failureproperty="seleniumTests.failed" errorproperty="seleniumTests.failed">
         <fileset dir="bin">
          <include name="demo1.class" />
         </fileset>
        </batchtest> 
       </junit>
      
      
       <junit printsummary="withOutAndErr" haltonfailure="no">
       <formatter type="xml" usefile="true" />
       <classpath refid="lib.classpath" />
       <batchtest fork="true" todir="results" failureproperty="seleniumTests.failed" errorproperty="seleniumTests.failed">
        <fileset dir="bin">
         <include name="demo2.class" />
        </fileset>
       </batchtest> 
       </junit>
      </parallel>
     </target>
     
     <target name="compile">
     <echo> compiling.....</echo>
      <javac srcdir="src" destdir="bin" classpathref="lib.classpath" />
     </target>
    </project>
  9. Now you run the testcases using build.xml file. Use the following command to run the testcases.
    ant run
    This will run demo1.class and demo2.class in parellel.