README.tutorial 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. Quick tutorial and overview
  2. ---------------------------
  3. Lettuce is a framework for doing Behaviour Driven Development (BDD).
  4. The idea behind BDD is that you first write down your requirements in
  5. the form of scenarios, then implement their behaviour.
  6. We do not plan on doing full BDD, but such a system should also help
  7. us make system tests. And, hopefully, being able to better identify
  8. what exactly is going wrong when a test fails.
  9. Lettuce is a python implementation of the Cucumber framework, which is
  10. a ruby system. So far we chose lettuce because we already need python
  11. anyway, so chances are higher that any system we want to run it on
  12. supports it. It only supports a subset of cucumber, but more cucumber
  13. features are planned. As I do not know much details of cucumber, I
  14. can't really say what is there and what is not.
  15. A slight letdown is that the current version does not support python 3.
  16. However, as long as the tool-calling glue is python2, this should not
  17. cause any problems, since these aren't unit tests; We do not plan to use
  18. our libraries directly, but only through the runnable scripts and
  19. executables.
  20. -----
  21. Features, Scenarios, Steps.
  22. Lettuce makes a distinction between features, scenarios, and steps.
  23. Features are general, well, features. Each 'feature' has its own file
  24. ending in .feature. A feature file contains a description and a number
  25. of scenarios. Each scenario tests one or more particular parts of the
  26. feature. Each scenario consists of a number of steps.
  27. So let's open up a simple one.
  28. -- example.feature
  29. Feature: showing off BIND 10
  30. This is to show BIND 10 running and that it answer queries
  31. Scenario: Starting bind10
  32. # steps go here
  33. --
  34. I have predefined a number of steps we can use, as we build test we
  35. will need to expand these, but we will look at them shortly.
  36. This file defines a feature, just under the feature name we can
  37. provide a description of the feature.
  38. The one scenario we have has no steps, so if we run it we should
  39. see something like:
  40. -- output
  41. > ./run_lettuce.sh
  42. Feature: showing off BIND 10
  43. This is to show BIND 10 running and that it answer queries
  44. Scenario: Starting bind10
  45. 1 feature (1 passed)
  46. 1 scenario (1 passed)
  47. 0 step (0 passed)
  48. --
  49. Let's first add some steps that send queries.
  50. --
  51. A query for www.example.com should have rcode REFUSED
  52. A query for www.example.org should have rcode NOERROR
  53. --
  54. Since we didn't start any bind10, dig will time out and the result
  55. should be an error saying it got no answer. Errors are in the
  56. form of stack traces (trigger by failed assertions), so we can find
  57. out easily where in the tests they occurred. Especially when the total
  58. set of steps gets bigger we might need that.
  59. So let's add a step that starts bind10.
  60. --
  61. When I start bind10 with configuration example.org.config
  62. --
  63. This is not good enough; it will start the process, but setting up
  64. b10-auth may take a few moments, so we need to add a step to wait for
  65. it to be started before we continue.
  66. --
  67. Then wait for bind10 auth to start
  68. --
  69. And let's run the tests again.
  70. --
  71. > ./run_lettuce.sh
  72. Feature: showing off BIND 10
  73. This is to show BIND 10 running and that it answer queries
  74. Scenario: Starting bind10
  75. When I start bind10 with configuration example.org.config
  76. Then wait for bind10 auth to start
  77. A query for www.example.com should have rcode REFUSED
  78. A query for www.example.org should have rcode NOERROR
  79. 1 feature (1 passed)
  80. 1 scenario (1 passed)
  81. 4 steps (4 passed)
  82. (finished within 2 seconds)
  83. --
  84. So take a look at one of those steps, let's pick the first one.
  85. A step is defined through a python decorator, which in essence is a regular
  86. expression; lettuce searches through all defined steps to find one that
  87. matches. These are 'partial' matches (unless specified otherwise in the
  88. regular expression itself), so if the step is defined with "do foo bar", the
  89. scenario can add words for readability "When I do foo bar".
  90. Each captured group will be passed as an argument to the function we define.
  91. For bind10, I defined a configuration file, a cmdctl port, and a process
  92. name. The first two should be self-evident, and the process name is an
  93. optional name we give it, should we want to address it in the rest of the
  94. tests. This is most useful if we want to start multiple instances. In the
  95. next step (the wait for auth to start), I added a 'of <instance>'. So if we
  96. define the bind10 'as b10_second_instance', we can specify that one here as
  97. 'of b10_second_instance'.
  98. --
  99. When I start bind10 with configuration second.config
  100. with cmdctl port 12345 as b10_second_instance
  101. --
  102. (line wrapped for readability)
  103. But notice how we needed two steps, which we probably always need (but
  104. not entirely always)? We can also combine steps; for instance:
  105. --
  106. @step('have bind10 running(?: with configuration ([\w.]+))?')
  107. def have_bind10_running(step, config_file):
  108. step.given('start bind10 with configuration ' + config_file)
  109. step.given('wait for bind10 auth to start')
  110. --
  111. Now we can replace the two steps with one:
  112. --
  113. Given I have bind10 running
  114. --
  115. That's it for the quick overview. For some more examples, with comments,
  116. take a look at features/example.feature. You can read more about lettuce and
  117. its features on http://www.lettuce.it, and if you plan on adding tests and
  118. scenarios, please consult the last section of the main README first.