unit testing with mxunit
DESCRIPTION
Unit Testing with MxUnit. Jason Michl. Presentation Contents. Installation of MxUnit Introduction to Unit Testing Example Application Simple Unit Tests Test Suites Complex Unit Tests. Installation of MxUnit. http://www.mxunit.org/doc/index.cfm?doc=installframework Summary: - PowerPoint PPT PresentationTRANSCRIPT
Jason Michl
Installation of MxUnitIntroduction to Unit TestingExample ApplicationSimple Unit TestsTest SuitesComplex Unit Tests
http://www.mxunit.org/doc/index.cfm?doc=installframework
Summary:Download.Unzip to root folder of website.Test: http://localhost/mxunit/index.cfm
Installation of MxUnitIntroduction to Unit TestingExample ApplicationSimple Unit TestsTest SuitesComplex Unit Tests
Unit testing is a means to improve code quality and reliability.
Individual units of code are tested according to specifications.
Defects can be identified before integration with other code.
Test-Driven DevelopmentWrite a test that failsWrite code that causes the test to passRepeat until code meets specifications
Asserts evaluate statements, and cause unit tests to fail when certain conditions are not met.Example:
AssertTrue(x eq y);If x equals y, then continue with the test.If x does not equal y, then the test fails.
Built-in asserts(Reminder: Assert functions fail when
their condition fails.)AssertTrue, AssertFalse, assertEquals,assertSame, assertNotSame
Full list:http://wiki.mxunit.org/display/default/Built-
In+Assertions
AssertTrue: Fails when condition is false.AssertTrue: Fails when condition is true.AssertEquals: Fails when arguments are not equal.AssertSame: Fails when arguments are not the same instance. (Arrays always fail.)AssertNotSame: Fails when arguments are the same instance. (Arrays always pass.)
MxUnit tests are written as components.Test components extend existing MxUnit components, and test functions through
asserts.
Example syntax:<cfcomponent displayname="testProjects" extends="mxunit.framework.TestCase">
<cffunction name="A_getProjectList_Exists" access="remote" returntype="void">
<cfscript>ProjectGateway = createObject("component", "components.project.ProjectGateway");assertTrue(isQuery(ProjectGateway.getProjectList()));
</cfscript> </cffunction>
</cfcomponent>
Installation of MxUnitIntroduction to Unit TestingExample ApplicationSimple Unit TestsTest SuitesComplex Unit Tests
Example applicationUsed to demonstrate test-driven
developmentPractical framework to build unit tests
around“Real-world” goal: organize software
development projects
TablesUsersUser TypesProjects
Team MembersNotes
(Note: Tables already have test data in them.)
Requirements for “getProjectList”Return a list of valid project recordsAccept multiple optional arguments as
filters
Basic tests for “getProjectList”Does function exist?Does function return a query?Does function return records from the
database?Does function accept and use
arguments?
Basic tests for “getProjectList”Does function return zero records, when
no arguments have been passed?Does function return all records, when
the “all” argument is passed?
Installation of MxUnitIntroduction to Unit TestingExample ApplicationSimple Unit TestsTest SuitesComplex Unit Tests
<cffunction name="A_getProjectList_Exists" access="remote" returntype="void"><cfscript>projectGatewayDemo = createObject("component", "components.project.projectGatewayDemo");assertTrue(isQuery(projectGatewayDemo.getProjectList()));</cfscript> </cffunction>
<cffunction name="getProjectList" access="public" returntype="query" output="false"></cffunction>
<cffunction name="A_getProjectList_Exists" access="remote" returntype="void"><cfscript>projectGatewayDemo = createObject("component", "components.project.projectGatewayDemo");assertTrue(isQuery(projectGatewayDemo.getProjectList()));</cfscript> </cffunction>
<cffunction name="getProjectList" access="public" returntype="query" output="false"><cfset var getProjectList = queryNew("empty") /><cfreturn getProjectList /></cffunction>
<cffunction name="C_getProjectList_Returns_Records_Passes" access="remote" returntype="void"><cfscript>projectGatewayDemo = createObject("component", "components.project.projectGatewayDemo");assertTrue((projectGatewayDemo.getProjectList().recordCount gt 0), "No records were returned.");</cfscript> </cffunction>
<cffunction name="getProjectList" access="public" returntype="query" output="false"><cfset var getProjectList = queryNew("empty") /><cfreturn getProjectList /></cffunction>
<cffunction name="C_getProjectList_Returns_Records_Passes" access="remote" returntype="void"><cfscript>projectGatewayDemo = createObject("component", "components.project.projectGatewayDemo");assertTrue((projectGatewayDemo.getProjectList().recordCount gt 0), "No records were returned.");</cfscript> </cffunction>
<cffunction name="getProjectList" access="public" returntype="query" output="false"><cfset var getProjectList = "" /><cfquery name="getProjectList" datasource="bugTrack">
SELECT *FROM prProjects
</cfquery><cfreturn getProjectList /></cffunction>
<cffunction name="D_getProjectList_Passes_createdBy_Passes" access="remote" returntype="void"><cfset projectGatewayDemo = createObject("component", "components.project.projectGatewayDemo") /><cfset getProjectList = projectGatewayDemo.getProjectList(createdBy = 1) /><cfloop query="getProjectList"><cfset assertTrue(getProjectList.createdBy eq 1, "Projects were returned with the wrong creator.") /></cfloop></cffunction>
<cffunction name="getProjectList" access="public" returntype="query" output="false"><cfset var getProjectList = "" /><cfquery name="getProjectList" datasource="bugTrack">
SELECT *FROM prProjects
</cfquery><cfreturn getProjectList /></cffunction>
<cffunction name="D_getProjectList_Passes_createdBy_Passes" access="remote" returntype="void"><cfset projectGatewayDemo = createObject("component", "components.project.projectGatewayDemo") /><cfset getProjectList = projectGatewayDemo.getProjectList(createdBy = 1) /><cfloop query="getProjectList"><cfset assertTrue(getProjectList.createdBy eq 1, "Projects were returned with the wrong creator.") /></cfloop></cffunction>
<cffunction name="getProjectList" access="public" returntype="query" output="false"><cfargument name="createdBy" default="" /><cfset var getProjectList = "" /><cfquery name="getProjectList" datasource="bugTrack">
SELECT *FROM prProjectsWHERE 0 = 0
<cfif len(arguments.createdBy)>AND createdBy = <cfqueryparam cfsqltype="cf_sql_integer"
value="#val(arguments.createdBy)#" /></cfif></cfquery><cfreturn getProjectList /></cffunction>
<cffunction name="G_getProjectList_Returns_Zero_Records_Passes" access="remote" returntype="void"><cfset projectGatewayDemo = createObject("component", "components.project.projectGatewayDemo") /><cfset getProjectList = projectGatewayDemo.getProjectList() /><cfset assertTrue(getProjectList.recordCount eq 0, "No arguments were sent. Query should have returned 0 results.") /></cffunction>
<cffunction name="getProjectList" access="public" returntype="query" output="false"><cfargument name="createdBy" default="" /><cfset var getProjectList = "" /><cfquery name="getProjectList" datasource="bugTrack">
SELECT *FROM prProjectsWHERE 0 = 0
<cfif len(arguments.createdBy)>AND createdBy = <cfqueryparam cfsqltype="cf_sql_integer"
value="#val(arguments.createdBy)#" /></cfif></cfquery><cfreturn getProjectList /></cffunction>
<cffunction name="G_getProjectList_Returns_Zero_Records_Passes" access="remote" returntype="void"><cfset projectGatewayDemo = createObject("component", "components.project.projectGatewayDemo") /><cfset getProjectList = projectGatewayDemo.getProjectList() /><cfset assertTrue(getProjectList.recordCount eq 0, "No arguments were sent. Query should have returned 0 results.") /></cffunction>
<cffunction name="getProjectList" access="public" returntype="query" output="false"><cfargument name="createdBy" default="" /><cfset var getProjectList = "" /><cfquery name="getProjectList" datasource="bugTrack">
SELECT *FROM prProjectsWHERE
<cfif len(arguments.createdBy) OR len(arguments.approvalStatus) OR len(arguments.projectID)>0 = 0
<cfelse>0 = 1
</cfif><cfif len(arguments.createdBy)>
AND createdBy = <cfqueryparam cfsqltype="cf_sql_integer" value="#val(arguments.createdBy)#" /></cfif></cfquery><cfreturn getProjectList /></cffunction>
<cffunction name="H_getProjectList_Returns_All_Records_Passes" access="remote" returntype="void">
<cfset projectGatewayDemo = createObject("component", "components.project.projectGatewayDemo") /><cfset getProjectList = projectGatewayDemo.getProjectList(all = 1) /><cfset assertTrue(getProjectList.recordCount gt 0, "The 'all' argument was sent. Query should have returned results.") /></cffunction>
<cffunction name="getProjectList" access="public" returntype="query" output="false"><cfargument name="createdBy" default="" /><cfset var getProjectList = "" /><cfquery name="getProjectList" datasource="bugTrack">
SELECT *FROM prProjectsWHERE
<cfif len(arguments.createdBy) OR len(arguments.approvalStatus) OR len(arguments.projectID)>0 = 0
<cfelse>0 = 1
</cfif><cfif len(arguments.createdBy)>
AND createdBy = <cfqueryparam cfsqltype="cf_sql_integer" value="#val(arguments.createdBy)#" /></cfif></cfquery><cfreturn getProjectList /></cffunction>
<cffunction name="H_getProjectList_Returns_All_Records_Passes" access="remote" returntype="void">
<cfset projectGatewayDemo = createObject("component", "components.project.projectGatewayDemo") /><cfset getProjectList = projectGatewayDemo.getProjectList(all = 1) /><cfset assertTrue(getProjectList.recordCount gt 0, "The 'all' argument was sent. Query should have returned results.") /></cffunction>
<cffunction name="getProjectList" access="public" returntype="query" output="false"><cfargument name="createdBy" default="" /><cfargument name="all" default="" /><cfset var getProjectList = "" /><cfquery name="getProjectList" datasource="bugTrack">
SELECT *FROM prProjectsWHERE
<cfif len(arguments.createdBy) OR len(arguments.approvalStatus) OR len(arguments.projectID) OR len(arguments.all)>
0 = 0<cfelse>
0 = 1</cfif><cfif len(arguments.createdBy)>
AND createdBy = <cfqueryparam cfsqltype="cf_sql_integer" value="#val(arguments.createdBy)#" /></cfif></cfquery><cfreturn getProjectList /></cffunction>
Example:http://127.0.0.1/mxunit/testCollection/unitTests/projectGatewayTestDemo.cfc?flush=&method=runTestRemote&event=home&output=ht
ml (shows each iteration of the development
cycle)
Example:http://127.0.0.1/mxunit/testCollection/unitTests/projectGatewayTest.cfc?flush=&method=runTestRemote&event=home&output=html
(shows final version of getProjectList)
Installation of MxUnitIntroduction to Unit TestingExample ApplicationSimple Unit TestsTest SuitesComplex Unit Tests
Tests can be stored in multiple files and accessed as needed.The “getProjectList” test is one of many tests available for BugTrack.
Other test files cover:Getting project member listsGetting project notesGetting user listsGetting user type lists
Test Suites allow you to run multiple test files at the same time.Example:
allGatewaySuite.cfm runs over 40 tests, across five files.
Example syntax:<cfset testSuite = createObject("component","mxunit.framework.TestSuite").TestSuite()/>
<cfset testSuite.addAll("mxunit.testcollection.unittests.projectGatewayTest")/> <cfset testSuite.addAll("mxunit.testcollection.unittests.projectMemberGatewayTest")/> <cfset testSuite.addAll("mxunit.testcollection.unittests.projectNotesGatewayTest")/> <cfset testSuite.addAll("mxunit.testcollection.unittests.userGatewayTest")/> <cfset testSuite.addAll("mxunit.testcollection.unittests.userTypeGatewayTest")/>
<cfset results = testSuite.run()/> <cfset writeOutput(results.getResultsOutput('html'))/>
(Show example suites in CFEclipse)
Example:http://127.0.0.1/mxunit/testCollection/allGatewaySuite.cfm
Installation of MxUnitIntroduction to Unit TestingExample ApplicationSimple Unit TestsTest SuitesComplex Unit Tests
Test-driven development can be used to successfully test complex applications.Example: BugTrack needs to pull a project, team members, and notes.We have unit tests for each of these, and now we need to test all of them together.
(Show examples in CFEclipse)