Testing And Mxunit In ColdFusion
Upcoming SlideShare
Loading in...5
×
 

Testing And Mxunit In ColdFusion

on

  • 3,106 views

This is a presentation I gave at the July 2011 NVCFUG meeting.

This is a presentation I gave at the July 2011 NVCFUG meeting.

Statistics

Views

Total Views
3,106
Views on SlideShare
3,106
Embed Views
0

Actions

Likes
2
Downloads
26
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Testing And Mxunit In ColdFusion Testing And Mxunit In ColdFusion Presentation Transcript

  • Testing and MXUnit
    In ColdFusion
    By DenardSpringle
    July 2011, NVCFUG
  • A testing framework for use in testing components (cfc’s)
    One piece of an integrated development methodology (e.g. Hudson, Ant and MXUnit)
    One tool in the Test Driven developers toolkit
    One tool in the Object-Oriented developers toolkit
    It is not useful for testing non-component templates or output
    HTML
    Javascript/Ajax
    CSS
    Etc.
    What is MXUnit?
  • A well organized SDLC environment includes:
    One or more development servers where code is developed and debugged by developers.
    One or more testing servers where code is tested using MXUnit (and/or other test frameworks), and is used by QA for regression testing.
    One or more production servers where fully tested and certified code is released.
    Dedicated testing servers prevent:
    Developers from crashing the test server
    Production being used to test code which mayleave datasources in an unknown state
    Writing complex extended DAO testing frameworks
    Test Environment
  • Download the latest MXUnit Framework.
    Unzip into webroot
    Test the install: http://myserver/mxunit/index.cfm
    Webroot is the root directory of the website you are testing.
    Installing MXUnit
  • The TestCase file is a component (a .cfc file)
    The filename either starts or ends with "Test"
    The component extends mxunit.framework.TestCase or extends a component that eventually extends mxunit.framework.TestCase
    The TestCase can contain setUp() and tearDown() functions that will run prior to and aftereach and everytest
    The TestCase can contain beforeTests() and afterTests() functions that will be run oncebefore and onceafteralltests
    Part One
    Anatomy of a Test Case
  • The TestCase can contain any number of public methods. Those public methods are considered tests regardless of their name, and MXUnit will run them as tests.
    Any private methods are not considered tests and will not be run by MXUnit
    Failures will be recorded as failures; errors as errors; and successes as successes
    Inside of your tests, you make assertions on the results of functions that you call on your component under test
    Part Two
    Anatomy of a Test Case
  • To very quickly get started, you can run the test by loading it in the browser and suffixing it with "?method=runTestRemote", like so: http://localhost/tests/MyTest.cfc?method=runTestRemote
    Example TestCase:
    Part Three
    Anatomy of a Test Case
  • Write the test first
    Watch the test fail
    Write the component
    Watch the test pass
    • Test Driven Development allows you to write your test cases before you begin development.
    • One caveat to TDD is the components you developare only as good as the tests you write. So getgood at writing tests if you want to use TDD.
    By Kent Beck
    Test Driven Development (TDD)
  • The core of unit testing, i.e. Assertions, are simple:
    You assert something, and if that assertion does not result in your expectation, the test fails.
    All code AFTER a failed assertion will NOT execute.
    Repeat: A failed assertion means the end of that test.
    This is why it's best practice to not load each test function with lots of assertions.
    A single failed assertion means that any subsequent assertions in a test will not execute and thus you won't know if those assertions indicate further problems in your code.
    In other words, one assertion per test function is strongly suggested
    as·sert - to demonstrate the existence of
    Assertions
  • assertTrue(boolean condition [,String message])
    assertTrue is one of the two "bread and butter" assertions in any testing framework. The philosophy is simple: you assert something to be true; if it's not, the test fails
    assertEquals (expected,actual[, String message])
    assertEquals is the other core assertion. Here, you're asserting that some actual result equals some expected result. This could be two numbers, two strings, two structs, whatever. For now, MXUnit follows the JUnit pattern of using a single assertEquals to compare any type of data.
    assertFalse(booleancondition [, String message])
    Built-In Assertions
  • assertSame (obj1,obj2 [,String message])
    Used to determine if the obj1 and obj2 refer to the same instance.Note that arrays in Adobe ColdFusion are passed by value, so, this will always fail for arrays.
    assertNotSame (obj1,obj2 [,String message])
    Used to determine if the obj1 and obj2 do not refer to the same instance.Note that arrays in Adobe ColdFusion are passed by value, so, this will always pass for arrays.
    Built-In Assertions
  • assertIsTypeOf (component obj, String type)
    Determines if obj is of type. type needs to be fully qualified (i.e. ‘core.beans.User’).
    assertIsXMLDoc (any xml [, String message])
    Determines if xml is a valid XML DOM object.
    assertIsArray (any obj1)
    Determines if the obj1 is a valid array.
    assertIsDefined*(any obj1)
    Determines if the obj1 has been defined in the available scope.
    These are extensions to the base set of assertions and are specific to ColdFusion.
    MXUnitAssertion Extensions
  • assertIsEmpty (any obj1)
    Determines if the obj1 is a 0 length string or NULL equivalent.
    assertIsEmptyArray (any obj1,[String message])
    Determines if the obj1 is an array with no elements.
    assertIsEmptyQuery(any obj1,[String message])
    Determines if the obj1 is a query with no rows.
    assertIsEmptyStruct (any obj1,[String message])
    Determines if the obj1 is a struct with no keys or values.
    MXUnitAssertion Extensions
  • assertIsQuery (any q)
    Determines if q is a valid ColdFusion query.
    assertIsStruct (any obj)
    Determines if obj is a valid ColdFusion structure.
    MXUnitAssertion Extensions
  • The steps for creating your custom assertion are as follows:
    Write a test for your assertion
    Write the assertion
    Decide how you want to load it: Always or only on selected tests.
    Assertion Rules:
    Your assertion will need to throw mxunit.exception.AssertionFailedError or use an existing assertion that throws this exception.
    If you want to have optional first or last parameter message, you will need to call normalizeArguments(arguments) in your code.
    Provides an easy way to add custom assertions to your tests without having to change the mxunit core.
    Custom Assertions
  • Data driven testing allows you to execute tests with a wide variety of input data. This can make creating and executing certain kinds of tests efficient and very powerful. Essentially, you provide a reference to a collection of data and MXUnit will iterate over that data and execute the test for each item in the collection.
    Data Providers
    Array
    Query
    List
    Excel/CSV
    Iterator
    mxunit:dataprovider=“<data provider>”
    With MXUnitdataproviders
    Data Driven Testing
  • Transactions
    The goal is to have a way to execute code that utilizes database logic (inserts, updates, deletes, etc.), test the results of the code, and set the state of the database back to a known state.
    Leveraging transactions is one way to achieve this.
    The process is to execute code and after assertions, roll back any transactions. Sounds simple ... it is and it isn't.
    ColdFusion is limited with transaction handling - you cannot have nested transactions and you need to use the <cftransaction ...> tag.
    A Test Adapter Pattern for DAO Testing
    DAO Test Adapter Pattern
  • Write the test first
    Extend the DAO component under test to DAOTestAdapter, or similar
    Refactorour DAO component: extracting the database logic to a package access method with no transaction handling
    Code this packageaccessed method within the transaction block of the public DAO method
    Create a method in DAOTestAdapter that overrides the DAO method under test and calls the package access method, but rolls back the transaction no matter what
    Run the test. The expected behavior is that data is inserted into the db, and the method returns true
    A Test Adapter Pattern for DAO Testing
    DAO Test Adapter Pattern
  • Resulting-State Assertion
    The resulting-state assertion tests data. It says "I'm doing something to my object that will change that object's data, or 'state'. I'm going to test that the resulting state of my object is as I expect". A simple example is the common "bank account" or "transaction" example: You have two accounts, you transfer $20 from one account to another, and you test that the first account is 20 bucks shorter and the second account has that 20 bucks.
    Different instances, same data
    The different-instances, same-data pattern is common in DAO testing. Essentially, we're asserting that two objects are different instances but contain the same data. In MXUnit, you can test for "different instance" by using the assertNotSame() assertion.
    **The terms here are taken from the outstanding book "Test-Driven" by LasseKoskela.
    Assertion Patterns
  • Guard Assertion
    The guard assertion is simply a slight variant on the resulting state assertion; typically, the difference is that toward the top of the test, before you get into the "guts" of your assertion(s), you check the object for some condition that you want to ensure exists before proceeding with the meat of your tests. Think of it as "If this condition isn't true, I want to fail right now because the rest of the tests don't matter". Usually the "guard" is just a simple assertion for equality, often to check that a "default" condition exists.
    Interaction Assertion
    With interaction assertions, we're testing to make sure an object and a collaborator worked together as we expected. A great example of an interaction is a "bean" style object, like perhaps a "User", and the DAO for that object, like a UserDAO
    Assertion Patterns
  • "Delta" Assertion
    Sometimes you can't assert an absolute equality (like "My list is now 5 elements long"). Sometimes, you have to assert equality relative to some previous state. Imagine you're hooking into some scheduling mechanism, for example. We don't know exactly what getTotalScheduled() will return at any given test run. Maybe it's 1. Maybe it's 30. Who knows. What we want to test is that when we schedule one additional thing, our scheduler's "totalScheduled" count increases by 1.
    This type of assertion, where we compare the state right before and right after performing some task, is called "delta", or difference, assertion.
    Assertion Patterns
  • MXUnit was built to make it as easy as possible to create tests and test suites.
    The steps for creating and running a TestSuite are:
    Create a ColdFusion page to run the suite
    Create a TestSuite object
    Tell the TestSuite what tests to add
    run() the TestSuite
    Print the output
    Run the suite in your web browser
    A TestSuite is a collection of tests that logically fit together.
    Creating and Running a TestSuite
  • http://www.mxunit.org
    Test Driven Development: By Example
    Test Driven: TDD and Acceptance TDD for Java Developers
    ColdFusion 9 Developer Tutorial – Chapter 14
    Marc Esher’sMXUnit Blog
    Additional Resources