Upload
vivekprahlad
View
15.875
Download
0
Embed Size (px)
DESCRIPTION
Presentation on Functional Testing Swing Applications with Frankenstein, an Open Source testing tool
Citation preview
© ThoughtWorks, 2006
Functional Testing Swing Applications with Frankenstein
Vivek Prahlad
© ThoughtWorks, 2006
Agenda
• Introduction to Frankenstein:– What is it?– Origin– How does it work?– Features
• Demo
© ThoughtWorks, 2006
What is Frankenstein
• Record and Play tool for testing Swing Applications• Support for testing Multithreaded Applications• Ruby driver• Easy extension
© ThoughtWorks, 2006
Origins
• Originated on a ThoughtWorks project with a Swing UI
– Multithreaded user interface
– Custom components (date pickers, etc.)
• Functional testing tools (commercial and open source) inadequate
– Slow, inadequate support for testing multithreaded apps
– Poor custom component support
– Build integration
– License cost for commercial tools
© ThoughtWorks, 2006
Features
• Record and play support
• Performance
• Ruby driver
• OGNL based assertions
• Multithreaded application support
• Easy extension / customization
• Straightforward integration
• HTML Reports
– Records screenshot on test step failure
– Reports can be customized
© ThoughtWorks, 2006
How does it work?
• Recorders hook on to Swing Event Queue
• Attach component specific listeners
• Record Events when the user interacts with the UI
– Event coalescing attempts to minimize script size
• Events can replay themselves
© ThoughtWorks, 2006
Record and play support
• Recording for reproducing bugs
• Not advisable to record entire scenarios
– Scripts become unmaintainable, difficult to read
• A better way is to record snippets of a user's workflow
– Can extract functions, parameterize
• Later, library functions can be used to write tests from scratch
© ThoughtWorks, 2006
Ruby driver
• Helps make tests modular
– Extract common steps into functions
– Parameterize functions
• Build a vocabulary for your application
• Test Suite support
© ThoughtWorks, 2006
Why Ruby?
• Ruby is a full-featured object oriented language
• Focus on readability, ease of use
• Allows test scripts to be modularized
• Lots of flexibility:
– Connect to databases
– Externalize strings (for i18n testing)
– CSV support
© ThoughtWorks, 2006
Recording + Ruby
• In combination, it is possible to build a testing vocabulary very close to the domain.
• Example:
login username, password
check_balance_is 1100
transfer 100.to destination_account_number
check_balance_is 1000
© ThoughtWorks, 2006
Assertions
• Control-rightclick on text and labels records assertions
– Need to add additional assertions manually using the Ruby driver
• Assert arbitrary properties via OGNL:
– assert “table_name” , “tableModel.rowCount” , “1”
– Equivalent to:
– assertEquals (1 , table.getTableModel().getRowCount())
• Can even make method calls!
– assert “table_name” “getValueAt(0,0)” , “cell text at row 0, column 0”
• Check out Ruby driver for examples
• http://www.ognl.org for information about OGNL
© ThoughtWorks, 2006
Testing Multithreaded apps
Two basic approaches exist:
• Arbitrary waits
– Make a guess about when an action will complete
• Explicit synchronization
– Look for indirect indications that actions are complete
© ThoughtWorks, 2006
Abitrary waits
• Tests are either:
– Slow, if the delays are more than required
– Fragile, if the delays are less than required
• Example:
login username, password
wait(20)
navigate inbox
select all
delete
© ThoughtWorks, 2006
Explicit Synchronization
• Tests tend to be verbose
• Example:
login username, password
wait_for_label(username)
navigate inbox
select all
delete
• wait_for_label in turn uses a delay within a loop
© ThoughtWorks, 2006
FrankensteinApproach
• Scripts do not need to worry about threading issues
• The framework does it for you
– Decide on a worker thread naming convention
– Frankenstein will monitor threads in the system after each test step
• Example
login username, password
navigate inbox
select all
delete
© ThoughtWorks, 2006
Integrating Frankenstein
• Logically name components ( using component.setName() )
– Naming strategy allows testing UIs where components aren't named
• Use PipingMain to get Frankenstein to launch your app
– Typical startup script: Java .. com.your.app.Main ..
– Change to:
– Java .. com.thoughtworks.frankenstein.application.PipingMain com.your.app.Main ..
• Use Ant's exec task to run Ruby test suite– Remember to launch app using PipingMain first!– May need delay before starting test run to account for app startup time <exec dir="${test.script.dir}" executable="ruby.exe"> <arg line="testsuite.rb"/> </exec>
© ThoughtWorks, 2006
Customizing Frankenstein
• Write a main class
/** * Launch the application under test via Frankenstein. */public class FrankensteinLauncher { public static void main(String[] args) { FrankensteinIntegration integration = new FrankensteinIntegration(YouMainClass.class); integration.registerEvent(YourCustomEvent.class); integration.registerRecorder(YourCustomRecorder.class); integration.start(args); }}
© ThoughtWorks, 2006
Customizing Frankenstein
• Register custom events, if any
– Most events can extend AbstractFrankensteinEvent
– Use AbstractEventTestCase
• Register custom recorders, if any
– Most recorders can extend from AbstractComponentRecorder
– Recorders created using IOC, so declare which of these you'll need in your recorder's constructor:
• NamingStrategy, Recorder, ComponentDecoder, ComponentVisibility
© ThoughtWorks, 2006
Customizing Frankenstein
Multithreading support:
• Decide on a worker thread naming convention, if required
– Use RegexWorkerThreadMonitor
– new FrankensteinIntegration(YourMain.class, new RegexWorkerThreadMonitor(“<thread name pattern>”);
• Or implement the WorkerThreadMonitor interface
© ThoughtWorks, 2006
Demo
© ThoughtWorks, 2006
Get it at
• https://svn.openqa.org/svn/frankenstein/trunk• Main site at http://www.openqa.org/frankenstein
© ThoughtWorks, 2006
Coming Soon
• Drag and Drop support
• Tree editor support
• Smart renderer decoders
– Pluggable renderer decoding support
• More assertions