Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

The Groovy Way of Testing with Spock

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Wird geladen in …3
×

Hier ansehen

1 von 40 Anzeige

The Groovy Way of Testing with Spock

Herunterladen, um offline zu lesen

Talk presented at Apache Con 2021 Groovy track.
Spock is a testing framework written in Groovy. I can confidently say that Spock is the best testing framework I ever used. The reason for this is the expressive specification language provided by the framework along with the productivity benefits offered by the Groovy language. Spock leverages the JUnit ecosystem and hence can co-exist with tests written in JUnit. In this presentation, we explore several features of Spock and understand how they add value to developers in terms of simplicity, readability, productivity, pragmatism.
We start by exploring the BDD style (given-when-then) structure of a Spock test and understand how it aids the developers to organise their thoughts and retain that clarity for the reader of the test as well. Then we move on to exploring the Spock way of writing assertions and understand the simplicity with which it provides expressive failure messages which aid in quick actionable feedback. Then we move on to realizing how Spock requires fewer tools and a smaller set of APIs to achieve functionalities such as mocking. In fact, Spock doesn't need an external library for mocking. In the final part of the presentation, we compare the approach of Spock in the areas of data-driven testing, ordering test cases, and co-existence with JUnit.

Talk presented at Apache Con 2021 Groovy track.
Spock is a testing framework written in Groovy. I can confidently say that Spock is the best testing framework I ever used. The reason for this is the expressive specification language provided by the framework along with the productivity benefits offered by the Groovy language. Spock leverages the JUnit ecosystem and hence can co-exist with tests written in JUnit. In this presentation, we explore several features of Spock and understand how they add value to developers in terms of simplicity, readability, productivity, pragmatism.
We start by exploring the BDD style (given-when-then) structure of a Spock test and understand how it aids the developers to organise their thoughts and retain that clarity for the reader of the test as well. Then we move on to exploring the Spock way of writing assertions and understand the simplicity with which it provides expressive failure messages which aid in quick actionable feedback. Then we move on to realizing how Spock requires fewer tools and a smaller set of APIs to achieve functionalities such as mocking. In fact, Spock doesn't need an external library for mocking. In the final part of the presentation, we compare the approach of Spock in the areas of data-driven testing, ordering test cases, and co-existence with JUnit.

Anzeige
Anzeige

Weitere Verwandte Inhalte

Diashows für Sie (20)

Ähnlich wie The Groovy Way of Testing with Spock (20)

Anzeige

Weitere von Naresha K (20)

Aktuellste (20)

Anzeige

The Groovy Way of Testing with Spock

  1. 1. 23 September 2021 The Groovy Way of Testing with Spock Naresha K @naresha_k https://blog.nareshak.com/
  2. 2. About me Developer, Architect & Tech Excellence Coach Founder & Organiser Bangalore Groovy User Group
  3. 3. Intention Conveying
  4. 4. import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; public class SampleJupiterTest { @Test @DisplayName("This test should pass if project is setup properly") public void thisTestShouldPassIfProjectIsSetupProperly() { assertThat(true).isTrue(); } }
  5. 5. https://martinfowler.com/bliki/BeckDesignRules.html
  6. 6. import spock.lang.Specification class SampleSpecification extends Specification { void "This test should pass if project is setup properly"() { expect: true } }
  7. 7. BDD Style Given - When - Then
  8. 8. def “files added to a bucket are available in the bucket”() { given: def filePath = Paths.get("src/test/resources/car.jpg") InputStream stream = Files.newInputStream(filePath) when: fileStorageService.storeFile(TARGET_BUCKET, "vehicles/123.jpg", stream) then: amazonS3Service.exists(TARGET_BUCKET, "vehicles/123.jpg") }
  9. 9. def "file can be stored in s3 storage and read"() { given: def filePath = Paths.get("src/test/resources/car.jpg") InputStream stream = Files.newInputStream(filePath) when: fileStorageService.storeFile(TARGET_BUCKET, "vehicles/123.jpg", stream) then: amazonS3Service.exists(TARGET_BUCKET, "vehicles/123.jpg") when: File file = fileStorageService.readFile(TARGET_BUCKET, "vehicles/123.jpg", Files.createTempFile(null, null).toAbsolutePath().toString()) then: file and: file.newInputStream().bytes = = filePath.bytes }
  10. 10. Power Asserts
  11. 11. void "list assertion example"() { given: List<Integer> numbers = [1, 2, 3] when: / / List<Integer> result = numbers.collect { it * 2} List<Integer> result = [2, 2, 6] then: result = = [2, 4, 6] } Condition not satis fi ed: result == [2, 4, 6] | | | false [2, 2, 6]
  12. 12. void "list contains expected element"() { expect: 10 in [2, 4, 6] } Condition not satis fi ed: 10 in [2, 4, 6] | false
  13. 13. void "assert all"() { expect: verifyAll { 10 in [2, 4, 6] 12 in [2, 4, 6] } } Multiple Failures (2 failures) org.spockframework.runtime.ConditionNotSatis fi edError: Condition not satis fi ed: 10 in [2, 4, 6] | false org.spockframework.runtime.ConditionNotSatis fi edError: Condition not satis fi ed: 12 in [2, 4, 6] | false
  14. 14. void "assert object by extracting field"() { when: List<Person> authors = [new Person(firstName: 'James', lastName: 'Gosling'), new Person(firstName: 'Kent', lastName: 'Beck')] then: authors*.lastName = = ['Gosling', 'Beck '] } Condition not satis fi ed: authors*.lastName == ['Gosling', 'Beck '] | | | | | false | [Gosling, Beck] [Person(James, Gosling), Person(Kent, Beck)]
  15. 15. void "assert with containsAll"() { when: List<Integer> numbers = [2, 4, 6] then: numbers.containsAll([10, 12]) } Condition not satis fi ed: numbers.containsAll([10, 12]) | | | false [2, 4, 6]
  16. 16. Data-Driven Testing
  17. 17. @Unroll void "#a + #b should be #expectedSum"() { when: def sum = a + b then: sum = = expectedSum where: a | b | expectedSum 10 | 10 | 20 20 | 20 | 40 }
  18. 18. Ordered Execution of Tests
  19. 19. @Stepwise class OrderedSpecification extends Specification { void "test 1"() { expect: true } void "test 2"() { expect: true } void "test 3"() { expect: true } }
  20. 20. @Stepwise class OrderedSpecification extends Specification { void "test 1"() { expect: true } void "test 2"() { expect: false } void "test 3"() { expect: true } }
  21. 21. Mocking
  22. 22. @Canonical class TalkPopularityService { AudienceCountService audienceCountService public boolean isPopularTalk(String talk) { def count = audienceCountService.getAudienceCount(talk) count > 100 ? true : false } } interface AudienceCountService { int getAudienceCount(String talk) }
  23. 23. class TalkPopularityServiceSpec extends Specification { private AudienceCountService audienceCountService = Mock() private TalkPopularityService talkPopularityService = new TalkPopularityService(audienceCountService) void "when audience count is 200 talk should be considered popular"() { given: String talk = "Whats new in Groovy 4" when: boolean isPopular = talkPopularityService.isPopularTalk(talk) then: isPopular = = true and: 1 * audienceCountService.getAudienceCount(talk) > > 200 } void "when audience count is 90 talk should be considered not popular"() { given: String talk = "Some talk" when: boolean isPopular = talkPopularityService.isPopularTalk(talk) then: isPopular = = false and: 1 * audienceCountService.getAudienceCount(talk) > > 90 } }
  24. 24. Spock 1.x - JUnit 4 Compatibility https://github.com/naresha/junitspock
  25. 25. public class Sputnik extends Runner implements Filterable, Sortable { / / code }
  26. 26. Spock - JUnit 5 Compatibility
  27. 27. public class SpockEngine extends HierarchicalTestEngine<SpockExecutionContext> { @Override public String getId() { return "spock"; } / / more code }
  28. 28. @Shared
  29. 29. public class SampleTest { private StateHolder stateHolder = new StateHolder(); @Test void test1() { / / use stateHolder } @Test void test2() { / / use stateHodler } } public class StateHolder { public StateHolder() { System.out.println("Instantiating StateHolder"); } }
  30. 30. public class SampleTest { private StateHolder stateHolder = new StateHolder(); @Test void test1() { / / use stateHolder } @Test void test2() { / / use stateHodler } } public class StateHolder { public StateHolder() { System.out.println("Instantiating StateHolder"); } } @BeforeEach private void setup() { stateHolder = new StateHolder(); }
  31. 31. public class SampleSharedStateTest { private StateHolder stateHolder; @BeforeAll void beforeAll() { stateHolder = new StateHolder(); } @Test void test1() { / / use shared stateHolder System.out.println(stateHolder); } @Test void test2() { / / use shared stateHodler System.out.println(stateHolder); } }
  32. 32. public class SampleSharedStateTest { private StateHolder stateHolder; @BeforeAll void beforeAll() { stateHolder = new StateHolder(); } @Test void test1() { / / use shared stateHolder System.out.println(stateHolder); } @Test void test2() { / / use shared stateHodler System.out.println(stateHolder); } } @BeforeAll method 'void com.nareshak.demo.SampleSharedStateTest.beforeAll()' must be static unless the test class is annotated with @TestInstance(Lifecycle.PER_CLASS).
  33. 33. public class SampleSharedStateTest { private static StateHolder stateHolder; @BeforeAll static void beforeAll() { stateHolder = new StateHolder(); } @Test void test1() { / / use shared stateHolder System.out.println(stateHolder); } @Test void test2() { / / use shared stateHodler System.out.println(stateHolder); } } Instantiating StateHolder com.nareshak.demo.StateHolder@5bea6e0 com.nareshak.demo.StateHolder@5bea6e0
  34. 34. class SharedStateSpec extends Specification{ @Shared private StateHolder stateHolder = new StateHolder() void "spec 1"() { println stateHolder expect: true } void "spec 2"() { println stateHolder expect: true } } com.nareshak.demo.StateHolder@53708326 com.nareshak.demo.StateHolder@53708326
  35. 35. class SharedStateSpec extends Specification{ @Shared private StateHolder stateHolder = new StateHolder() void "spec 1"() { println stateHolder expect: true } void "spec 2"() { println stateHolder expect: true } } com.nareshak.demo.StateHolder@53708326 com.nareshak.demo.StateHolder@53708326 @Shared private StateHolder stateHolder void setupSpec() { stateHolder = new StateHolder() }
  36. 36. And The most important Reason ???
  37. 37. https://github.com/naresha/apachecon2021spock
  38. 38. Thank You

×