Make Your Testing Groovy

Make Your Testing Groovy

Make your testing Groovy © ASERT 2006 Dr Paul King Groovy Lead for Object Computing Inc. - 2016 @paulk_asert http:/slideshare.net/paulk_asert/make-tests-groovy https://github.com/paulk-asert/MakeTestingGroovy Why test with Groovy? with test Why © ASERT 2006-2016 Why test with Groovy? • Wrong first question! • … but great second question? © ASERT 2006 - 2016 • Consider first the task at hand and the organization and people fit! “People Fit” / “Organization Fit” • People – Developers (familiarity with languages) – Testers (tools language familiarity) – Responsibility to create/run/maintain – BAs/SMEs (ability to read technical tests) © ASERT 2006 – Consider both development and maintenance - 2016 – Expected feedback from tests (JUnit/Reports) • Organization – Maturity level – Degree of automation – Tools in use – Need for adaptability Why Test With Groovy? • Advantages – Easy to learn – Particularly good for Java shops – Easy to plug and play different testing tools – Good community & tools for professional agile © ASERT 2006 • Disadvantages - 2016 – Requires JVM – Less advantages if your developers using Python, .Net, PHP – Maybe your testers already know Ruby Scripting/Dynamic Languages • Advantages – Lend themselves to succinct code/DSLs – Powerful – Increased Refactoring – Increased Reuse © ASERT 2006 – Less prone to Brittleness - 2016 – Flexibility for tool integration – Open APIs provide extensibility • Disadvantages – Can be too low level – Sometimes less tool support Test Characteristics… • Coverage/Traceability – Requirement coverage/traceability – Code coverage: line, branch, path, state – Transactional Tracing © ASERT 2006 • Purpose – Unit, Integration, System, Customer - 2016 • Manageability – Removing duplication – Managing lifecycle: shared setUp/tearDown (@Before @After) …Test Characteristics • Handling test data – Data-driven, databases, Spreadsheets, tables, keywords, random, model-driven – Large Test Volumes © ASERT 2006 – Speed of feedback, performance testing • Tool evolution, longevity, cost, - 2016 support, documentation – Open Source/Commercial, Critical mass/popularity • Combinability Key Testing Practices… • Use testing DSL’s • Look to move up the testing stack – It used to be all about the driver – Now the driver is hidden in the © ASERT 2006 framework or tool stack • Apply good testing practices - 2016 – Pareto analysis, bug clusters, mutation testing, test early, all pairs/equivalence partitions/orthogonal array testing, risk-based test selection, coding for testability, use CI, boundary value analysis, defensive programming …Key Testing Practices • Plug and play testing tools – Run different drivers with different runners and different tools • Complement automated tests with © ASERT 2006 exploration • Expand testing scope - 2016 – Test environment readiness, test deployments Groovy and Testing Tool Spectrum* © ASERT 2006 - 2016 * Tools/libraries/frameworks don't always neatly fall into one category – still useful conceptually What is Groovy? “Groovy is like a super version of Java. It leverages Java features but adds productivity features and provides great flexibility and © ASERT 2006 extensibility.” - 2016 Groovy = Java – boiler plate code + closures (1st class FP) + extensible type system + runtime & compile-time metaprogramming + flexible grammar (DSLs) + scripting & GDK library Groovy starter System.out.println("Hello, World!"); // supports Java syntax println 'Hello, World!' // but can remove some syntax String name = 'Guillaume' // Explicit typing/awareness println "$name, I'll get the car." // Gstring (interpolation) def longer = """${name}, the car is in the next row.""" // multi-line, implicit type © ASERT 2006 assert 0.5 == 1/2 // BigDecimal equals() assert 0.1 + 0.2 == 0.3 // and arithmetic - 2016 def printSize(obj) { // implicit/duck typing print obj?.size() // safe dereferencing } def pets = ['ant', 'bee', 'cat'] // literal list syntax pets.each { pet -> // closure support assert pet < 'dog' // overloading '<' on String } // or: for (pet in pets)... Target audience • Testing for developers – Organising tests – Running tests – Data generation – Mocking – What can be tested – Code coverage • Testing beyond developers – Structuring – Better reporting – Data-driven – Domain specific language (DSL) – Test coverage Testing Frameworks • None • JUnit 3 • JUnit 4 • JUnit 5 • TestNG • Spock Testing Frameworks • None ??? • JUnit 3 • JUnit 4 • JUnit 5 • TestNG • Spock Testing Frameworks • None ??? – Groovy deems testing so important that it comes with built-in testing: – Built-in asserts, mocks – Built-in JUnit 3 GroovyTestCase and utilities – Built-in runners for tests – Bundled JUnit 4 • JUnit 3 • JUnit 4 • JUnit 5 • TestNG • Spock Built-in assertions class Converter { static celsius (fahrenheit) { (fahrenheit - 32) * 5 / 9 } } © ASERT 2006 - 2016 import static Converter.celsius assert 20 == celsius(68) assert 35 == celsius(95) assert -17 == celsius(0).toInteger() assert 0 == celsius(32) Built-in assertions • But what about errors? © ASERT 2006 • Groovy’s power Assert mechanism gives a friendly description of what went wrong - 2016 Built-in assertions • But what about errors? © ASERT 2006 • Groovy’s power Assert mechanism gives a friendly description of what went wrong - 2016 GroovyTestCase (extends JUnit 3) import org.junit.Assert import static Converter.celsius import static org.junit.Assert.assertEquals class SimpleGroovyTest extends GroovyTestCase { © ASERT 2006 void testShouldConvert() { assert Converter.celsius(68) == 20 assert Converter.celsius(212) == 100, "Should convert boiling" assertEquals("Should convert freezing", 0.0, celsius(32.0)) - 2016 assertEquals("Should convert nearly freezing", 0.0, celsius(32.1), 0.1) } } JUnit4 import org.junit.Test import static org.junit.Assert.assertEquals import static Converter.celsius class SimpleJUnit4Test { © ASERT 2006 @Test void shouldConvert() { assert celsius(68) == 20 - 2016 assert celsius(212) == 100, "Should convert boiling" assertEquals("Should convert freezing", 0.0, celsius(32.0)) assertEquals("Also for nearly freezing", 0.0, celsius(32.1), 0.1) } } JUnit5 @Grab('org.junit.platform:junit-platform-runner:1.0.0-M2') @Grab('org.junit.jupiter:junit-jupiter-engine:5.0.0-M2') import org.junit.jupiter.api.Test import org.junit.platform.runner.JUnitPlatform import org.junit.runner.RunWith import static Converter.celsius © ASERT 2006 @RunWith(JUnitPlatform) class ConverterJUnit5Tests { - @Test 2016 void freezing() { assert celsius(32) == 0 } @Test void boiling() { assert celsius(212) == 100 } } JUnit5 @Grab('org.junit.platform:junit-platform-runner:1.0.0-M2') @Grab('org.junit.jupiter:junit-jupiter-engine:5.0.0-M2') import org.junit.jupiter.api.Test import org.junit.platform.runner.JUnitPlatform import org.junit.runner.RunWith import static Converter.celsius © ASERT 2006 @RunWith(JUnitPlatform) class ConverterJUnit5Tests { - @Test 2016 void freezing() { assert celsius(32) == 0 } @Test void boiling() { assert celsius(212) == 100 } } Spock - BDD style @Grab('org.spockframework:spock-core:1.0-groovy-2.4') import spock.lang.Specification class GivenWhenThenSpec extends Specification { def "test adding a new item to a set"() { © ASERT 2006 given: def items = [4, 6, 3, 2] as Set - 2016 when: items << 1 then: items.size() == 5 } } Parameterized import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import org.junit.runners.Parameterized.Parameters import static Converter.celsius @RunWith(Parameterized) class DataDrivenJUnitTest { private c, f, scenario @Parameters static scenarios() {[ [0, 32, 'Freezing'], © ASERT 2006 [20, 68, 'Garden party conditions'], [35, 95, 'Beach conditions'], [100, 212, 'Boiling'] ]*.toArray()} - 2016 DataDrivenJUnitTest(c, f, scenario) this.c = c this.f = f this.scenario = scenario } @Test void convert() { def actual = celsius(f) def msg = "$scenario: ${f}°F should convert into ${c}°C" assert c == actual, msg } } Spock @Grab('org.spockframework:spock-core:1.0-groovy-2.4') import spock.lang.* import static Converter.celsius class SpockDataDriven extends Specification { def "test temperature scenarios"() { expect: © ASERT 2006 celsius(tempF) == tempC where: - 2016 scenario | tempF || tempC 'Freezing' | 32 || 0 'Garden party conditions' | 68 || 20 'Beach conditions' | 95 || 35 'Boiling' | 212 || 100 } } Spock - Celsius @Grab('org.spockframework:spock-core:1.0-groovy-2.4') import spock.lang.* import static Converter.celsius class SpockDataDriven extends Specification { @Unroll def "Scenario #scenario: #tempFºF should convert to #tempCºC"() { expect: celsius(tempF) == tempC © ASERT 2006 where: scenario | tempF || tempC 'Freezing' | 32 || 0 - 2016 'Garden party conditions' | 68 || 20 'Beach conditions' | 95 || 34 'Boiling' | 212 || 100 } } Spock - Celsius @Grab('org.spockframework:spock-core:1.0-groovy-2.4') import spock.lang.* import static Converter.celsius class SpockDataDriven extends Specification { @Unroll def "Scenario #scenario: #tempFºF should convert to #tempCºC"() { expect: celsius(tempF) == tempC © ASERT 2006 where: scenario | tempF || tempC 'Freezing' | 32 || 0 - 2016 'Garden party conditions' | 68 || 20 'Beach conditions' | 95 || 34 'Boiling' | 212 || 100 } } Spock - Mocks @Grab('org.spockframework:spock-core:1.0-groovy-2.4') import spock.lang.Specification class SpockMock extends Specification { def "buy ticket for a movie theater"() { given: © ASERT 2006 def purchase = new Purchase("Lord of the Rings", 2) MovieTheater theater = Mock() theater.hasSeatsAvailable("Lord of

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    74 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us