Showing posts with label Testing. Show all posts
Showing posts with label Testing. Show all posts

Friday, January 18, 2013

Performance Testing with JMeter


The JMeter is desktop/ command line Java application designed to load test functional behavior and measure performance. It was originally designed for testing Web Applications.

This article shows how to use it for testing webapps.



Preparations


  • Install JMeter on your laptop. On Linux is as package in some central repositories.
  • Install htop on your server. htop is top on steroids. You can find it on rpmforge repos.


Getting Started

It shows how to define basic request for server and dump reports.

1. Adding Thread Group to Test Plan

  • Number of Threads: Defines how many threads (users) will access to the server.
  • RampUp Period: In what time period the requests shall be made. Zero means immediately.


2. Adding Reguest to Thread Group
Type in the Server name, Port number, Path.



3. Adding Listeners to Thread Group
Listeners used to capture and presentation of results.
For example: Spline Visualizer, Summary Report, View Requests in Table.




4. Starting basic test.
Go to server and run htop for watching server status dynamically. You can see: CPU and memory usage, Swap usage, processes, …

From JMeter main menu Run>Start. During testing watch the behavior of the server on htop console. It may help to understand more your server.

After completing the test explore results in Listeners sections: errors, times, responses,...


Using proxy server for recording complex requests


For a definition of complex requests is best to use the HTTP Proxy Server.
  1. Insert HTTP Proxy Server component to WorkBench fork. Define port and click to Start button.
  2. Insert Recording Controller to Thread Group.


Connecting to HTTP Proxy Server
Go into the settings of your favorite web browser and connect to the proxy server.


Now, in your web browser go to your webapp and make requests. For example fill out and submit the form. All your requests are stored in the Record Conroller.



At the end don´t forget stop the HTTP Proxy server. Start test and watch results.

Conclusion

JMeter offers a lot of others components: Timers, Logic Controllers, Assertions for checking responses. You can test SOAP and XML/RPC services, JDBC connections, FTP requests.

JMeter can be run from the command line. You can test automatically from scripts, or on server without GUI.

Friday, August 6, 2010

Grails: Unit testing

Source:


The core of the testing plugin is the grails.test.GrailsUnitTestCase class.


mockDomain(class, testInstances)

Takes a class and makes mock implementations of all the domain class methods.

example:
void testSomething() {
  def testInstances=[]
  mockDomain(Song, testInstances)
  assertEquals(0, Song.count())
  new Song(name:"Supper's Ready").save()
  assertEquals(1, Song.count())
}

example:
def testInstances = [ new Item(code: "NH-4273997", name: "Laptop"),
                new Item(code: "EC-4395734", name: "Lamp"),
                new Item(code: "TF-4927324", name: "Laptop") ]
mockDomain(Item, testInstances)



mockForConstraintsTests(class, testInstances)

Highly specialised mocking for domain classes and command objects that allows you to check whether the constraints are behaving as you expect them to.

example:
class Book {
  String title
  String author
    static constraints = {
        title(blank: false, unique: true)
        author(blank: false, minSize: 5)
    }
}

class BookTests extends GrailsUnitTestCase {
  void testConstraints() {
      def existingBook = new Book(title: "Misery", author: "Stephen King")
      mockForConstraintsTests(Book, [ existingBook ])
        // Validation should fail if both properties are null.
        def book = new Book()
        assertFalse book.validate()
        assertEquals "nullable", book.errors["title"]
        assertEquals "nullable", book.errors["author"]
        // So let's demonstrate the unique and minSize constraints.
        book = new Book(title: "Misery", author: "JK")
        assertFalse book.validate()
        assertEquals "unique",     book.errors["title"]
        assertEquals "minSize", book.errors["author"]
        // Validation should pass!
        book = new Book(title: "The Shining", author: "Stephen King")
        assertTrue book.validate()
    }
}



mockFor(class)

 

This range determines how many times you expect the method to be called, so if the number of invocations falls outside of that range then an assertion error will be thrown. If no range is specified, a default of "1..1" is assumed.

The closure arguments should match the number and types of the mocked method, but otherwise you are free to add whatever you want in the body.


example:
def strictControl = mockFor(MyService)
strictControl.demand.someMethod(0..2) { String arg1, int arg2 -> … }
strictControl.demand.static.aStaticMethod {-> … }

example:
class MyService { def otherService
    String createSomething() {        
        def stringId = otherService.newIdentifier()        
        def item = new Item(code: stringId, name: "Bangle")        
        item.save()        
        return stringId      
   }
   
   int countItems(String name) {        
        def items = Item.findAllByName(name)        
        return items.size()    
   }
}

import grails.test.GrailsUnitTestCase
class MyServiceTests extends GrailsUnitTestCase {
    void testCreateSomething() {
        // Mock the domain class.
        mockDomain(Item)

        // Mock the "other" service.
        String testId = "NH-12347686"
        def otherControl = mockFor(OtherService)
        otherControl.demand.newIdentifier(1..1) {-> return testId }

        // Initialise the service and test the target method.
        def testService = new MyService()
        testService.otherService = otherControl.createMock()

        def retval = testService.createSomething()

        // Check that the method returns the identifier returned by the
        // mock "other" service and also that a new Item instance has
        // been saved.
        def testInstances = Item.list()        
        assertEquals testId, retval
        assertEquals 1, testInstances.size()
        assertTrue testInstances[0] instanceof Item
    }

    void testCountItems() {
        // Mock the domain class, this time providing a list of test
        // Item instances that can be searched.
        def testInstances = [ new Item(code: "NH-4273997", name: "Laptop"),
                         new Item(code: "EC-4395734", name: "Lamp"),
                         new Item(code: "TF-4927324", name: "Laptop") ]
        mockDomain(Item, testInstances)
       

// Initialise the service and test the target method.

def testService = new MyService()
        assertEquals 2, testService.countItems("Laptop")
        assertEquals 1, testService.countItems("Lamp")
        assertEquals 0, testService.countItems("Chair")
    }
}


mockLogging(class, enableDebug = false)

Adds a mock "log" property to a class. Any messages passed to the mock logger are echoed to the console.




mockController(class)

Adds mock versions of the dynamic controller properties and methods to the given class. This is typically used in conjunction with the ControllerUnitTestCase class.

Mock controller properties available in unit tests
  • request
  • response
  • session
  • flash
  • params
  • redirectArgs
  • renderArgs
  • template
  • modelAndView
example:
class PostControllerUnitTests extends grails.test.ControllerUnitTestCase {
     void testShow() {
          mockDomain(User, [
                    new User(userId: "glen"),
                    new User(userId: "peter") ]
          this.controller.params.id = "peter"
          def model = this.controller.show()
          assertEquals "peter", model["viewUser"]?.userId
     }
}

example - action returns a model:
void testList() {
     mockDomain(Album, [ new Album(title: "Odelay"),
     new Album(title: "Abbey Road"] )
     def model = controller.list()
     assertEquals 2, model.albumList.size()
}

example - Testing the Contents of the Response:
void testIndex() {
     controller.index()
     assertEquals "Welcome to the gTunes store!", controller.response.contentAsString
}

example - contents of render args
render(view: "show", model:[album:Album.get(params.id)])

void testShow() {
     mockDomain(Album, new Album(id:1, title: "Aha Shake Heartbreak"))
     mockParams.id = 1
     controller.show()
     assertEquals "show", renderArgs.view
     assertEquals 1, renderArgs.model.album.id
     assertEquals "Aha Shake Heartbreak", renderArgs.model.album.title
}

mockParams: this property provides a mock implementation of the params object that you can populate with values before calling the controller. In addition to a mock implementation of the params object, the ControllerUnitTestCase class provides the following properties that mock various aspects of the controller API:
  • mockRequest
  • mockResponse
  • mockSession
  • mockParams
  • mockFlash
note:ControllerUnitTestCase not support some dynamic method. For instance: bindData(). Then is better use integration testing, or you can add this method to controller:
 example:
this.controller.metaClass.bindData = { obj, params ->
           params.each { key, value ->
                       obj."$key" = value
               }
       }

this.controller.metaClass.getGrailsApplication = {-> return [config: [:]] }


example - redirect:
//in controller
redirect(controller: "post", action: "list")

// in test
assertEquals "post", this.controller.redirectArgs["controller"]
assertEquals "list", this.controller.redirectArgs["action"]

example - testing action:
def register = {
     if(request.method == 'POST') {
          def u = new User(params)
          if(u.password != params.confirm) {
                u.errors.rejectValue("password", "user.password.dontmatch")
                return [user:u]
          }else if(u.save()) {
                session.user = u
                redirect(controller:"store")
          }else {
                return [user:u]
          }

     }
}

void testRegistrationFailed() {
     mockRequest.method = 'POST'
     mockDomain(User)

     mockParams.login = ""
     def model = controller.register()

     assertNull mockSession.user
     assert model
     def user = model.user
     assert user.hasErrors()
     assertEquals "blank", user.errors.login
     assertEquals "nullable", user.errors.password
     assertEquals "nullable",
     user.errors.firstName
     assertEquals "nullable", user.errors.firstName
}

void testRegistrationSuccess() {
     mockRequest.method = 'POST'
     mockDomain(User)

     mockParams.login = "joebloggs"
     mockParams.password = "password"
     mockParams.confirm = "password"
     mockParams.firstName = "Joe"
     mockParams.lastName = "Blogs"

     def model = controller.register()

     assertEquals 'store',redirectArgs.controller
     assertNotNull mockSession.user
}

example - test Command
def login = { LoginCommand cmd ->
     if(request.method == 'POST') {
        if(!cmd.hasErrors()) {
             session.user = cmd.getUser()
             redirect(controller:'store')
        }else {
             render(view:'/store/index', model:[loginCmd:cmd])
        }
     }else {
            render(view:'/store/index')
     }
}

void testLoginUserNotFound() {
     mockRequest.method = 'POST'
     mockDomain(User)
     MockUtils.prepareForConstraintsTests(LoginCommand)
     def cmd = new LoginCommand(login:"fred", password:"letmein")
     cmd.validate()
     controller.login(cmd)
     assertTrue cmd.hasErrors()
     assertEquals "user.not.found", cmd.errors.login
     assertEquals "/store/index", renderArgs.view
}

void testLoginPasswordInvalid() {
     mockRequest.method = 'POST'
     mockDomain(User, [new User(login:"fred", password:"realpassword")])
     MockUtils.prepareForConstraintsTests(LoginCommand)
     def cmd = new LoginCommand(login:"fred", password:"letmein")
     cmd.validate()
     controller.login(cmd)
     assertTrue cmd.hasErrors()
     assertEquals "user.password.invalid", cmd.errors.password
     assertEquals "/store/index", renderArgs.view
}

void testLoginSuccess() {
     mockRequest.method = 'POST'
     mockDomain(User, [new User(login:"fred", password:"letmein")])
     MockUtils.prepareForConstraintsTests(LoginCommand)
     def cmd = new LoginCommand(login:"fred", password:"letmein")
     cmd.validate()
     controller.login(cmd)
     assertFalse cmd.hasErrors()
     assertNotNull mockSession.user
     assertEquals "store", redirectArgs.controller
}



mockTagLib(class)

Adds mock versions of the dynamic taglib properties and methods to the given class. This is typically used in conjunction with the TagLibUnitTestCase class.

example:
class MyTagLib {
     def repeat = { attrs, body ->
            attrs.times?.toInteger().times { n ->
                      body(n)
             }
      }
}

<g:repeat times="3">Hello number ${it}</g:repeat>

import grails.test.*
class MyTagLibTests extends TagLibUnitTestCase {

     MyTagLibTests() {
         super(MyTagLib)
     }

     void testRepeat() {
         tagLib.repeat(times: '2') {
            'output<br/>'
         }

     assertEquals 'output<br/>output<br/>', tagLib.out.toString()
     }
}

example:





One oddity is the empty map ([:]) as an argument, which is required because the tag
expects an attribute map as the first argument. If we were passing in at least one attri-
bute value, we could use the implicit syntax instead:
tagLib.isLoggedIn(attr1: "value") { ... }


In order to check whether the appropriate text has been generated by the tag, we
then perform a toString() on the out property and compare it to the expected value

mockConfig

In your controller you have to use org.codehaus.groovy.grails.commons.ConfigurationHolder. Then is very simple used mockConfig.

example:
private void takeOverDemoTestsets(school) {
       def String[] ids = ConfigurationHolder.config.cz.svse.testy.demo.testsets.ids.split(",")
       ids.each(){ id ->
           def testset = Testset.get(id)
           if(testset){
               school.addToTestsets( testset.clone(  school ) )
               log.info(" add testset: ${testset.title}" )              
           }
   }
}

class SchoolControllerTests extends grails.test.ControllerUnitTestCase {
  
    protected void setUp() {
       super.setUp()
           
       mockDomain(Testset, [
                   new Testset(id:1, title:"one"),
                   new Testset(id:2, title:"two")
       ])

       mockDomain(School,[])

       mockConfig ('''
               cz.svse.testy.demo.testsets.ids="1,2"
       ''')     
    }

    protected void tearDown() {
           super.tearDown()
    }
  
    void testTakeOverDemoTestsets() {
           
       def school = new School()
       assertEquals 0, school.testsets.size()

       this.controller.takeOverDemoTestsets(school)
       assertEquals 2, school.testsets.size()                
    }
}