The document discusses testing for telephony applications. It notes that telephony apps are long-running with both constrained and unconstrained inputs, as well as external call interactions happening concurrently. Testing approaches include integration testing using tools like sipp and Cucumber-VoIP, functional testing of single classes, and unit testing of methods with various input types. It recommends designing for concurrency, using state machines, and mocking dependencies for testing concurrency.
3. How Telephony Testing Is Different
• Apps are long-running code
Friday, August 10, 12
4. How Telephony Testing Is Different
• Apps are long-running code
• Inputs may be more constrained (DTMF)
Friday, August 10, 12
5. How Telephony Testing Is Different
• Apps are long-running code
• Inputs may be more constrained (DTMF)
• Or they may be less constrained (IM, Voice)
Friday, August 10, 12
6. How Telephony Testing Is Different
• Apps are long-running code
• Inputs may be more constrained (DTMF)
• Or they may be less constrained (IM, Voice)
• Lots of things are happening concurrently
Friday, August 10, 12
7. How Telephony Testing Is Different
• Apps are long-running code
• Inputs may be more constrained (DTMF)
• Or they may be less constrained (IM, Voice)
• Lots of things are happening concurrently
• External call interactions (conf, barge)
Friday, August 10, 12
8. How Telephony Testing Is Different
• Apps are long-running code
• Inputs may be more constrained (DTMF)
• Or they may be less constrained (IM, Voice)
• Lots of things are happening concurrently
• External call interactions (conf, barge)
• XMPP Events
Friday, August 10, 12
10. How Telephony Testing Is Familiar
• Same Tooling: rspec, mocha, cucumber,
factory_girl, guard, rcov, rake
Friday, August 10, 12
11. How Telephony Testing Is Familiar
• Same Tooling: rspec, mocha, cucumber,
factory_girl, guard, rcov, rake
• Still draw lines between M, V and C
Friday, August 10, 12
12. How Telephony Testing Is Familiar
• Same Tooling: rspec, mocha, cucumber,
factory_girl, guard, rcov, rake
• Still draw lines between M, V and C
• Good class design is important
Friday, August 10, 12
13. How Telephony Testing Is Familiar
• Same Tooling: rspec, mocha, cucumber,
factory_girl, guard, rcov, rake
• Still draw lines between M, V and C
• Good class design is important
Friday, August 10, 12
14. How Telephony Testing Is Familiar
• Same Tooling: rspec, mocha, cucumber,
factory_girl, guard, rcov, rake
• Still draw lines between M, V and C
• Good class design is important
• It’s Just Ruby
Friday, August 10, 12
16. Philosophy: SRP
• Single Responsibility Principle
Friday, August 10, 12
17. Philosophy: SRP
• Single Responsibility Principle
• If you need to use “and” to describe the
purpose of a class, you are probably
breaking this rule
Friday, August 10, 12
18. Philosophy: SRP
• Single Responsibility Principle
• If you need to use “and” to describe the
purpose of a class, you are probably
breaking this rule
• SRP is key to making classes testable
Friday, August 10, 12
20. SRP Example
• Class purpose: “To
schedule calls and to
place them”
Friday, August 10, 12
21. SRP Example
• Class purpose: “To
schedule calls and to
place them”
• Testing requires mocking
methods within the same
class
Friday, August 10, 12
22. SRP Example
• Class purpose: “To
schedule calls and to
place them”
• Testing requires mocking
methods within the same
class
• Non-trivial work to swap
calling mechanism
Friday, August 10, 12
25. Philosophy: Tell, Don’t Ask
• Tell an object to do its work
• Don’t ask for its state then ask it to do
something
Friday, August 10, 12
26. Philosophy: Tell, Don’t Ask
• Tell an object to do its work
• Don’t ask for its state then ask it to do
something
• Works Hand-in-Hand with SRP
Friday, August 10, 12
27. Philosophy: Tell, Don’t Ask
• Tell an object to do its work
• Don’t ask for its state then ask it to do
something
• Works Hand-in-Hand with SRP
Friday, August 10, 12
28. Philosophy: Tell, Don’t Ask
• Tell an object to do its work
• Don’t ask for its state then ask it to do
something
• Works Hand-in-Hand with SRP
Friday, August 10, 12
31. Philosophy: Prefer/Share Immutable
• Methods should only use passed-in data
• Avoid instance vars or other shared state
Friday, August 10, 12
32. Philosophy: Prefer/Share Immutable
• Methods should only use passed-in data
• Avoid instance vars or other shared state
• Especially helpful with concurrent code
Friday, August 10, 12
33. Philosophy: Prefer/Share Immutable
• Methods should only use passed-in data
• Avoid instance vars or other shared state
• Especially helpful with concurrent code
• ... but makes testing in general easier
Friday, August 10, 12
44. Levels of Testing
• Integration Testing
• End-to-End
Friday, August 10, 12
45. Levels of Testing
• Integration Testing
• End-to-End
• Provide predefined inputs
Friday, August 10, 12
46. Levels of Testing
• Integration Testing
• End-to-End
• Provide predefined inputs
• Verify outputs
Friday, August 10, 12
47. Levels of Testing
• Integration Testing
• End-to-End
• Provide predefined inputs
• Verify outputs
• Mock as little as possible
Friday, August 10, 12
53. Functional Testing
• Test just one unit in isolation
Friday, August 10, 12
54. Functional Testing
• Test just one unit in isolation
• Typical unit is a single class
Friday, August 10, 12
55. Functional Testing
• Test just one unit in isolation
• Typical unit is a single class
• Test function of class
but do not make
assertions about
internal state
Friday, August 10, 12
57. Unit Testing
• Most common form of testing
Friday, August 10, 12
58. Unit Testing
• Most common form of testing
• Test that a given unit (typically: method)
behaves the way you expect
Friday, August 10, 12
59. Unit Testing
• Most common form of testing
• Test that a given unit (typically: method)
behaves the way you expect
• Make sure to test:
Friday, August 10, 12
60. Unit Testing
• Most common form of testing
• Test that a given unit (typically: method)
behaves the way you expect
• Make sure to test:
• Valid inputs
Friday, August 10, 12
61. Unit Testing
• Most common form of testing
• Test that a given unit (typically: method)
behaves the way you expect
• Make sure to test:
• Valid inputs
• Invalid inputs
Friday, August 10, 12
62. Unit Testing
• Most common form of testing
• Test that a given unit (typically: method)
behaves the way you expect
• Make sure to test:
• Valid inputs
• Invalid inputs
• Error Conditions
Friday, August 10, 12
66. Testing Concurrency
• Design with a concurrency model or library
Friday, August 10, 12
67. Testing Concurrency
• Design with a concurrency model or library
• Celluloid, EventMachine
Friday, August 10, 12
68. Testing Concurrency
• Design with a concurrency model or library
• Celluloid, EventMachine
• Use State Machines to guarantee sequence
Friday, August 10, 12
69. Testing Concurrency
• Design with a concurrency model or library
• Celluloid, EventMachine
• Use State Machines to guarantee sequence
• Mock non-blocking dependent operations
with blocking mocks
Friday, August 10, 12
70. Testing Concurrency
• Design with a concurrency model or library
• Celluloid, EventMachine
• Use State Machines to guarantee sequence
• Mock non-blocking dependent operations
with blocking mocks
• Always provide a timeout
Friday, August 10, 12
71. Testing Concurrency
https://github.com/benlangfeld/countdownlatch
Friday, August 10, 12
72. Testing Concurrency
https://github.com/benlangfeld/countdownlatch
Friday, August 10, 12
74. Can You Hear Me Now?
Tackling Testing Telephony Ben Klang
bklang@mojolingo.com
spkr8.com/t/12971 @bklang Github/Twitter
Thanks to Ben Langfeld for his
assistance with this presentation
@benlangfeld
Friday, August 10, 12