Merge lp:~fgimenez/autopilot/doc-nitpicks into lp:autopilot

Proposed by Federico Gimenez
Status: Needs review
Proposed branch: lp:~fgimenez/autopilot/doc-nitpicks
Merge into: lp:autopilot
Diff against target: 259 lines (+29/-33)
5 files modified
docs/appendix/protocol.rst (+1/-1)
docs/faq/faq.rst (+5/-5)
docs/guides/good_tests.rst (+6/-7)
docs/tutorial/advanced_autopilot.rst (+11/-13)
docs/tutorial/getting_started.rst (+6/-7)
To merge this branch: bzr merge lp:~fgimenez/autopilot/doc-nitpicks
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Leo Arias (community) Approve
Review via email: mp+256632@code.launchpad.net

Commit message

Doc nitpicks

Description of the change

Doc nitpicks

To post a comment you must log in.
lp:~fgimenez/autopilot/doc-nitpicks updated
552. By Federico Gimenez

fixed number of nodes selected

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Leo Arias (elopio) :
review: Approve
lp:~fgimenez/autopilot/doc-nitpicks updated
553. By Federico Gimenez

removed reduntant parentheses

554. By Federico Gimenez

Line wrapped according to pep8

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Unmerged revisions

554. By Federico Gimenez

Line wrapped according to pep8

553. By Federico Gimenez

removed reduntant parentheses

552. By Federico Gimenez

fixed number of nodes selected

551. By Federico Gimenez

more doc nitpicks

550. By Federico Gimenez

fixed indentation

549. By Federico Gimenez

doc nitpicks

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'docs/appendix/protocol.rst'
--- docs/appendix/protocol.rst 2013-10-28 22:07:57 +0000
+++ docs/appendix/protocol.rst 2015-04-23 08:35:00 +0000
@@ -88,7 +88,7 @@
88 a -> d;88 a -> d;
89 }89 }
9090
91a query of ``/foo/bar`` will select two objects. This is allowed, but not always what we want. There are several ways to avoid this, they will be covered later in this document.91a query of ``/foo/bar`` will select three objects. This is allowed, but not always what we want. There are several ways to avoid this, they will be covered later in this document.
9292
93Relative Queries93Relative Queries
94++++++++++++++++94++++++++++++++++
9595
=== modified file 'docs/faq/faq.rst'
--- docs/faq/faq.rst 2015-01-25 23:08:51 +0000
+++ docs/faq/faq.rst 2015-04-23 08:35:00 +0000
@@ -37,7 +37,7 @@
37Q. What type of applications can autopilot test?37Q. What type of applications can autopilot test?
38================================================38================================================
3939
40Autopilot works with severall different types of applications, including:40Autopilot works with several different types of applications, including:
41 * The Unity desktop shell.41 * The Unity desktop shell.
42 * Gtk 2 & 3 applications.42 * Gtk 2 & 3 applications.
43 * Qt4, Qt5, and Qml applications.43 * Qt4, Qt5, and Qml applications.
@@ -61,8 +61,8 @@
61* Some features require several assertions to prove that the feature is working correctly. For example, you may wish to verify that the 'Save' dialog box opens correctly, using the following code::61* Some features require several assertions to prove that the feature is working correctly. For example, you may wish to verify that the 'Save' dialog box opens correctly, using the following code::
6262
63 self.assertThat(save_win.title, Eventually(Equals("Save Document")))63 self.assertThat(save_win.title, Eventually(Equals("Save Document")))
64 self.assertThat(save_win.visible, Equals(True))64 self.assertTrue(save_win.visible)
65 self.assertThat(save_win.has_focus, Equals(True))65 self.assertTrue(save_win.has_focus)
6666
67* Some tests need to wait for the application to respond to user input before the test continues. The easiest way to do this is to use the :class:`~autopilot.matchers.Eventually` matcher in the middle of your interaction with the application. For example, if testing the `Firefox <http://www.mozilla.org/en-US/>`_ browsers ability to print a certain web comic, we might produce a test that looks similar to this::67* Some tests need to wait for the application to respond to user input before the test continues. The easiest way to do this is to use the :class:`~autopilot.matchers.Eventually` matcher in the middle of your interaction with the application. For example, if testing the `Firefox <http://www.mozilla.org/en-US/>`_ browsers ability to print a certain web comic, we might produce a test that looks similar to this::
6868
@@ -80,7 +80,7 @@
80 self.assertThat(self.app.print_dialog.open, Eventually(Equals(True)))80 self.assertThat(self.app.print_dialog.open, Eventually(Equals(True)))
81 self.keyboard.press_and_release('Enter')81 self.keyboard.press_and_release('Enter')
82 # ensure something was sent to our faked printer:82 # ensure something was sent to our faked printer:
83 self.assertThat(self.fake_printer.documents_printed, Equals(1))83 self.assertEqual(self.fake_printer.documents_printed, 1)
8484
85In general, autopilot tests are more relaxed about the 'one assertion per test' rule. However, care should still be taken to produce tests that are as small and understandable as possible.85In general, autopilot tests are more relaxed about the 'one assertion per test' rule. However, care should still be taken to produce tests that are as small and understandable as possible.
8686
@@ -134,7 +134,7 @@
134 keyboard = Keyboard.create('OSK')134 keyboard = Keyboard.create('OSK')
135 with keyboard.focused_type(text_area) as kb:135 with keyboard.focused_type(text_area) as kb:
136 kb.type("Hello World.")136 kb.type("Hello World.")
137 self.assertThat(text_area.text, Equals("Hello World"))137 self.assertEqual(text_area.text, "Hello World")
138 # At this point now the OSK has been swiped away.138 # At this point now the OSK has been swiped away.
139 self.assertThat()139 self.assertThat()
140140
141141
=== modified file 'docs/guides/good_tests.rst'
--- docs/guides/good_tests.rst 2015-01-22 16:18:06 +0000
+++ docs/guides/good_tests.rst 2015-04-23 08:35:00 +0000
@@ -123,18 +123,18 @@
123 text_win = self.open_new_application_window("Text Editor", maximized=True)123 text_win = self.open_new_application_window("Text Editor", maximized=True)
124124
125 self.assertTrue(text_win.is_maximized)125 self.assertTrue(text_win.is_maximized)
126 self.assertThat(self.panel.title, Equals(text_win.title))126 self.assertEqual(self.panel.title, text_win.title)
127 sleep(.25)127 sleep(.25)
128128
129 calc_win = self.open_new_application_window("Calculator")129 calc_win = self.open_new_application_window("Calculator")
130 self.assertThat(self.panel.title, Equals(calc_win.application.name))130 self.assertEqual(self.panel.title, calc_win.application.name)
131131
132 icon = self.launcher.model.get_icon_by_desktop_id(text_win.application.desktop_file)132 icon = self.launcher.model.get_icon_by_desktop_id(text_win.application.desktop_file)
133 launcher = self.launcher.get_launcher_for_monitor(self.panel_monitor)133 launcher = self.launcher.get_launcher_for_monitor(self.panel_monitor)
134 launcher.click_launcher_icon(icon)134 launcher.click_launcher_icon(icon)
135135
136 self.assertTrue(text_win.is_focused)136 self.assertTrue(text_win.is_focused)
137 self.assertThat(self.panel.title, Equals(text_win.title))137 self.assertEqual(self.panel.title, text_win.title)
138138
139This test can be simplified into the following:139This test can be simplified into the following:
140140
@@ -150,7 +150,7 @@
150 launcher.click_launcher_icon(icon)150 launcher.click_launcher_icon(icon)
151151
152 self.assertTrue(text_win.is_focused)152 self.assertTrue(text_win.is_focused)
153 self.assertThat(self.panel.title, Equals(text_win.title))153 self.assertEqual(self.panel.title, text_win.title)
154154
155Here's what we changed:155Here's what we changed:
156156
@@ -168,8 +168,7 @@
168 2. Avoid words like "should" in favor of stronger words like "must".168 2. Avoid words like "should" in favor of stronger words like "must".
169 3. Contain a one-line summary of the test.169 3. Contain a one-line summary of the test.
170170
171Additionally, they should:171Additionally, they should include the launchpad bug number (if applicable).
172 1. Include the launchpad bug number (if applicable).
173172
174**Good Example:**173**Good Example:**
175174
@@ -308,7 +307,7 @@
308 sleep(2)307 sleep(2)
309 self.keyboard.press_and_release("Alt+F4")308 self.keyboard.press_and_release("Alt+F4")
310 sleep(2)309 sleep(2)
311 self.assertThat(self.dash.visible, Equals(False))310 self.assertFalse(self.dash.visible)
312311
313This test uses two ``sleep`` calls. The first makes sure the dash has had time to open before the test continues, and the second makes sure that the dash has had time to respond to our key presses before we start testing things.312This test uses two ``sleep`` calls. The first makes sure the dash has had time to open before the test continues, and the second makes sure that the dash has had time to respond to our key presses before we start testing things.
314313
315314
=== modified file 'docs/tutorial/advanced_autopilot.rst'
--- docs/tutorial/advanced_autopilot.rst 2015-01-23 09:47:02 +0000
+++ docs/tutorial/advanced_autopilot.rst 2015-04-23 08:35:00 +0000
@@ -58,19 +58,19 @@
5858
59 def test_empty_string_returns_no_results(self):59 def test_empty_string_returns_no_results(self):
60 self.dictionary_app.enter_search_term("")60 self.dictionary_app.enter_search_term("")
61 self.assertThat(len(self.dictionary_app.results), Equals(0))61 self.assertEqual(len(self.dictionary_app.results), 0)
6262
63 def test_whitespace_string_returns_no_results(self):63 def test_whitespace_string_returns_no_results(self):
64 self.dictionary_app.enter_search_term(" \t ")64 self.dictionary_app.enter_search_term(" \t ")
65 self.assertThat(len(self.dictionary_app.results), Equals(0))65 self.assertEqual(len(self.dictionary_app.results), 0)
6666
67 def test_punctuation_string_returns_no_results(self):67 def test_punctuation_string_returns_no_results(self):
68 self.dictionary_app.enter_search_term(".-?<>{}[]")68 self.dictionary_app.enter_search_term(".-?<>{}[]")
69 self.assertThat(len(self.dictionary_app.results), Equals(0))69 self.assertEqual(len(self.dictionary_app.results), 0)
7070
71 def test_garbage_string_returns_no_results(self):71 def test_garbage_string_returns_no_results(self):
72 self.dictionary_app.enter_search_term("ljdzgfhdsgjfhdgjh")72 self.dictionary_app.enter_search_term("ljdzgfhdsgjfhdgjh")
73 self.assertThat(len(self.dictionary_app.results), Equals(0))73 self.assertEqual(len(self.dictionary_app.results), 0)
7474
75The main problem here is that there's a lot of typing in order to change exactly one thing (and this hypothetical test is deliberately short, to ease clarity. Imagine a 100 line test case!). Another approach is to make the entire thing one large test (*don't do this either*)::75The main problem here is that there's a lot of typing in order to change exactly one thing (and this hypothetical test is deliberately short, to ease clarity. Imagine a 100 line test case!). Another approach is to make the entire thing one large test (*don't do this either*)::
7676
@@ -84,7 +84,7 @@
84 )84 )
85 for input in bad_strings:85 for input in bad_strings:
86 self.dictionary_app.enter_search_term(input)86 self.dictionary_app.enter_search_term(input)
87 self.assertThat(len(self.dictionary_app.results), Equals(0))87 self.assertEqual(len(self.dictionary_app.results), 0)
8888
8989
90This approach makes it easier to add new input strings, but what happens when just one of the input strings stops working? It becomes very hard to find out which input string is broken, and the first string that breaks will prevent the rest of the test from running, since tests stop running when the first assertion fails.90This approach makes it easier to add new input strings, but what happens when just one of the input strings stops working? It becomes very hard to find out which input string is broken, and the first string that breaks will prevent the rest of the test from running, since tests stop running when the first assertion fails.
@@ -102,7 +102,7 @@
102102
103 def test_bad_strings_return_no_results(self):103 def test_bad_strings_return_no_results(self):
104 self.dictionary_app.enter_search_term(self.input)104 self.dictionary_app.enter_search_term(self.input)
105 self.assertThat(len(self.dictionary_app.results), Equals(0))105 self.assertEqual(len(self.dictionary_app.results), 0)
106106
107Autopilot will run the ``test_bad_strings_return_no_results`` once for each scenario. On each test, the values from the scenario dictionary will be mapped to attributes of the test case class. In this example, that means that the 'input' dictionary item will be mapped to ``self.input``. Using scenarios has several benefits over either of the other strategies outlined above:107Autopilot will run the ``test_bad_strings_return_no_results`` once for each scenario. On each test, the values from the scenario dictionary will be mapped to attributes of the test case class. In this example, that means that the 'input' dictionary item will be mapped to ``self.input``. Using scenarios has several benefits over either of the other strategies outlined above:
108108
@@ -122,7 +122,7 @@
122Test Logging122Test Logging
123============123============
124124
125Autopilot integrates the `python logging framework <http://docs.python.org/2/library/logging.html>`_ into the :class:`~autopilot.testcase.AutopilotTestCase` class. Various autopilot components write log messages to the logging framework, and all these log messages are attached to each test result when the test completes. By default, these log messages are shown when a test fails, or if autopilot is run with the ``-v`` option.125Autopilot integrates the `python logging framework <http://docs.python.org/3/library/logging.html>`_ into the :class:`~autopilot.testcase.AutopilotTestCase` class. Various autopilot components write log messages to the logging framework, and all these log messages are attached to each test result when the test completes. By default, these log messages are shown when a test fails, or if autopilot is run with the ``-v`` option.
126126
127Test authors are encouraged to write to the python logging framework whenever doing so would make failing tests clearer. To do this, there are a few simple steps to follow:127Test authors are encouraged to write to the python logging framework whenever doing so would make failing tests clearer. To do this, there are a few simple steps to follow:
128128
@@ -140,7 +140,7 @@
140 logger.warning("This is a warning")140 logger.warning("This is a warning")
141 logger.error("This is an error")141 logger.error("This is an error")
142142
143For more information on the various logging levels, see the `python documentation on Logger objects <http://docs.python.org/2/library/logging.html#logger-objects>`_. All messages logged in this way will be picked up by the autopilot test runner. This is a valuable tool when debugging failing tests.143For more information on the various logging levels, see the `python documentation on Logger objects <http://docs.python.org/3/library/logging.html#logger-objects>`_. All messages logged in this way will be picked up by the autopilot test runner. This is a valuable tool when debugging failing tests.
144144
145Environment Patching145Environment Patching
146====================146====================
@@ -536,10 +536,8 @@
536 class SpecificQLabel(CustomProxyObjectBase):536 class SpecificQLabel(CustomProxyObjectBase):
537537
538 def validate_dbus_object(path, state):538 def validate_dbus_object(path, state):
539 if (path.endswith('object_we_want') or539 return (path.endswith('object_we_want') or
540 state['some_property'] == 'desired_value'):540 state['some_property'] == 'desired_value')
541 return True
542 return False
543541
544This method should return True if the object matches this custom proxy class, and False otherwise. If more than one custom proxy class matches an object, a :exc:`ValueError` will be raised at runtime.542This method should return True if the object matches this custom proxy class, and False otherwise. If more than one custom proxy class matches an object, a :exc:`ValueError` will be raised at runtime.
545543
@@ -550,7 +548,7 @@
550 class TestCase(AutopilotTestCase):548 class TestCase(AutopilotTestCase):
551549
552 def setUp(self):550 def setUp(self):
553 super(TestCase, self).setUp()551 super().setUp()
554 self.app = self.launch_test_application(552 self.app = self.launch_test_application(
555 '/path/to/the/application',553 '/path/to/the/application',
556 emulator_base=CustomProxyObjectBase)554 emulator_base=CustomProxyObjectBase)
557555
=== modified file 'docs/tutorial/getting_started.rst'
--- docs/tutorial/getting_started.rst 2015-02-19 20:26:30 +0000
+++ docs/tutorial/getting_started.rst 2015-04-23 08:35:00 +0000
@@ -12,7 +12,7 @@
12 autopilot/<projectname>/12 autopilot/<projectname>/
13 autopilot/<projectname>/tests/13 autopilot/<projectname>/tests/
1414
15The ``autopilot`` folder can be anywhere within your project's source tree. It will likely contain a `setup.py <http://docs.python.org/3/distutils/setupscript.html>`_ file.15The ``autopilot`` folder can be anywhere within your project's source tree. It will likely contain a `setup.py <https://setuptools.pypa.io/en/latest/setuptools.html>`_ file.
1616
17The ``autopilot/<projectname>/`` folder is the base package for your autopilot tests. This folder, and all child folders, are python packages, and so must contain an `__init__.py file <http://docs.python.org/3/tutorial/modules.html#packages>`_. If you ever find yourself writing custom proxy classes (This is an advanced topic, and is covered here: :ref:`custom_proxy_classes`), they should be imported from this top-level package.17The ``autopilot/<projectname>/`` folder is the base package for your autopilot tests. This folder, and all child folders, are python packages, and so must contain an `__init__.py file <http://docs.python.org/3/tutorial/modules.html#packages>`_. If you ever find yourself writing custom proxy classes (This is an advanced topic, and is covered here: :ref:`custom_proxy_classes`), they should be imported from this top-level package.
1818
@@ -51,7 +51,7 @@
51 class MyTests(AutopilotTestCase):51 class MyTests(AutopilotTestCase):
5252
53 def setUp(self):53 def setUp(self):
54 super(MyTests, self).setUp()54 super().setUp()
55 # This code gets run before every test!55 # This code gets run before every test!
5656
57 def test_something(self):57 def test_something(self):
@@ -89,7 +89,7 @@
89A Simple Test89A Simple Test
90=============90=============
9191
92To demonstrate the material covered so far, this selection will outline a simple application, and a single test for it. Instead of testing a third-party application, we will write the simplest possible application in Python and Qt4. The application, named 'testapp.py', is listed below::92To demonstrate the material covered so far, this section will outline a simple application, and a single test for it. Instead of testing a third-party application, we will write the simplest possible application in Python and Qt4. The application, named 'testapp.py', is listed below::
9393
94 #!/usr/bin/env python94 #!/usr/bin/env python
9595
@@ -114,7 +114,6 @@
114114
115 from autopilot.testcase import AutopilotTestCase115 from autopilot.testcase import AutopilotTestCase
116 from os.path import abspath, dirname, join116 from os.path import abspath, dirname, join
117 from testtools.matchers import Equals
118117
119 class MainWindowTitleTests(AutopilotTestCase):118 class MainWindowTitleTests(AutopilotTestCase):
120119
@@ -134,7 +133,7 @@
134 app_root = self.launch_application()133 app_root = self.launch_application()
135 main_window = app_root.select_single('QMainWindow')134 main_window = app_root.select_single('QMainWindow')
136135
137 self.assertThat(main_window.windowTitle, Equals("Hello World"))136 self.assertEqual(main_window.windowTitle, "Hello World")
138137
139138
140Note that we have made the test method as readable as possible by hiding the complexities of finding the full path to the application we want to test. Of course, if you can guarantee that the application is in :envvar:`PATH`, then this step becomes a lot simpler.139Note that we have made the test method as readable as possible by hiding the complexities of finding the full path to the application we want to test. Of course, if you can guarantee that the application is in :envvar:`PATH`, then this step becomes a lot simpler.
@@ -283,7 +282,7 @@
283 app_root = self.launch_application()282 app_root = self.launch_application()
284 main_window = app_root.select_single('AutopilotHelloWorld')283 main_window = app_root.select_single('AutopilotHelloWorld')
285284
286 self.assertThat(main_window.windowTitle, Equals("Hello World"))285 self.assertEqual(main_window.windowTitle, "Hello World")
287286
288287
289 class ButtonResponseTests(HelloWorldTestBase):288 class ButtonResponseTests(HelloWorldTestBase):
@@ -309,7 +308,7 @@
309308
310 self.assertThat(response.text, Eventually(Equals('Response: Goodbye')))309 self.assertThat(response.text, Eventually(Equals('Response: Goodbye')))
311310
312In addition to the new class, ``ButtonResponseTests``, you'll notice a few other changes. First, two new import lines were added to support the new tests. Next, the existing ``MainWindowTitleTests`` class was refactored to subclass from a base class, ``HelloWorldTestBase``. The base class contains the ``launch_application`` method which is used for all test cases. Finally, the object type of the main window changed from ``QMainWindow`` to ``AutopilotHelloWorld``. The change in object type is a result of our test application being refactored into a class called ``AutopilotHelloWorld``.311In addition to the new class, ``ButtonResponseTests``, you'll notice a few other changes. First, three new import lines were added to support the new tests. Next, the existing ``MainWindowTitleTests`` class was refactored to subclass from a base class, ``HelloWorldTestBase``. The base class contains the ``launch_application`` method which is used for all test cases. Finally, the object type of the main window changed from ``QMainWindow`` to ``AutopilotHelloWorld``. The change in object type is a result of our test application being refactored into a class called ``AutopilotHelloWorld``.
313312
314.. otto:: **Be careful when identifing user interface controls**313.. otto:: **Be careful when identifing user interface controls**
315314

Subscribers

People subscribed via source and target branches