Merge lp:~senan/ubuntu-autopilot-tests/DiskUsageAnalyser into lp:ubuntu-autopilot-tests

Proposed by Prabhendu V Senan
Status: Superseded
Proposed branch: lp:~senan/ubuntu-autopilot-tests/DiskUsageAnalyser
Merge into: lp:ubuntu-autopilot-tests
Diff against target: 156 lines (+149/-0)
1 file modified
ubuntu_autopilot_tests/DiskUsageAnalyser/test_diskUsageAnalyser.py (+149/-0)
To merge this branch: bzr merge lp:~senan/ubuntu-autopilot-tests/DiskUsageAnalyser
Reviewer Review Type Date Requested Status
Dan Chapman  Pending
Review via email: mp+193087@code.launchpad.net

This proposal has been superseded by a proposal from 2014-01-26.

To post a comment you must log in.
Revision history for this message
Dan Chapman  (dpniel) wrote :

First off this is a great start :-) Well Done. Its always the trickiest part learning what you can and can't do with autopilot.

So my first thoughts are (and keeping in mind the near release of autopilot 1.4),

1) the test window title failed on my box. Due to having a different locale where analyzer is actually analyser. So to make this work you would probably be better testing the title with something like Contains('Disk Usage'). Then we miss the strange locale issues.

Note that if you wanted the test to pass on any locale you could assertThat(title, NotEquals(None)) and then assertIsInstance(title, unicode). This will test that the title contains text (we don't know what the title text will be, but we can test the title is there and that its unicode.

2) the other 3 tests are very similar so you could probably break them up a little. My first point with this is you are finishing each test outside of the test function with the self.disk_usage_display_common() call. Ideally you should be finishing each test with asserts as the last lines inside your test function. This way you can see the intended end result of the test i.e "the treeviewmap and ringmap should display a 'x' directory/folder" try and do the setup type parts to get you to the point you need outside the test function and then come back once setup to test the thing you are actually testing

another thing when entering /home in the file chooser dialog you should use the provided function in the keyboard class 'focused_type' so for example once you have clicked the toggle button and the entry is visible you could use something like this

entry = self.app.select_single('GtkFileChooserEntry')
with self.keyboard.focused_type(entry) as kb:
    kb.type('/home')
    self.assertThat(entry.text, Equals('/home'))
    kb.press_and_release('Enter')

This will get the entries focus and type the text see http://unity.ubuntu.com/autopilot/api/input.html#autopilot.input.Keyboard.focused_type

There is also some changes needed to be made for 1.4 if you check this link about boolean properties are now represented correctly and not 1/0. http://unity.ubuntu.com/autopilot/porting/porting.html#gtk-tests-and-boolean-parameters

I'll leave it there for now and see how we fair once these changes are made.

Feel free to ping myself or balloons if your are getting stuck :-)

Revision history for this message
Dan Chapman  (dpniel) wrote :

Senan hey,

So what i was trying to say in IRC is that you are repeating code in a few of your tests. So lets use the test_scan_local_folder for this example and you will be able to use it in the other test just as easy

lets start with this part of the test

def test_scan_local_folder(self):
    self.gear_menu_option_button = self.app.select_single(BuilderName='menu-button')
    self.pointing_device.move_to_object(self.gear_menu_option_button)
    self.pointing_device.click()
    self.create_scan_folder_menu_item = self.app.select_single('GtkModelMenuItem',action_name= 'win.scan-folder')
    self.pointing_device.move_to_object(self.create_scan_folder_menu_item)
    self.pointing_device.click()

you use this same process in two tests but selecting a different GtkModelMenuItem for each test, so this can be broken out into its own function and you pass in the name of the GtkModelMenuItem you need for each test

you should use more descriptive names than this, i'm just showing examples

def test_scan_local_folder(self):
    self.open_folder_dialog('win.scan-folder')
    # .. Rest of test ..

def open_folder_dialog(self, item_name):
    gear_menu_option_button = self.app.select_single(BuilderName='menu-button')
    self.pointing_device.click_object(self.gear_menu_option_button)
    #now select the passed in menu item
    create_scan_folder_menu_item = self.app.select_single('GtkModelMenuItem',action_name=item_name)
    self.pointing_device.click_object(create_scan_folder_menu_item)

so now for your tests you can reuse this and just pass in the action_name of the menu item
i.e
self.open_folder_dialog('win.scan-folder')
self.open_folder_dialog('win.scan-remote')

Thats an example of what i mean by breaking up the tests a bit and re-using code makes it easier to maintain.

Regarding my comments on finishing the tests inside the test function, currently on some of the tests you call self.disk_usage_display_common() as the last call of your test, this in effect takes us out of the test function and we have to go looking elswhere to see what the intent of the test function is trying to assert. Each test method should work like

def Test
    1) setup the test (this is the setup function which starts baobab)
    2) get the test into the required state for this test. ( so using functions outside the test function )
    3) once in the required state for the test, assert what we want to test. as the last part of the test function

take a look at the gedit test as an example the test are only testing one thing only then move on to the next test.

so as an example you could break tests up like

1) test we can open home folder ( but we do not check the folder is being displayed properly thats another test)
2) test that the tree map diplays the home folder
3) test trying to open a folder that doesn't exist.

Each test should not depend on any other test. So create functions of common code that you can use to get a test to its 'required state'

I hope this is of some help

61. By Prabhendu V Senan

Renamed DiskUsageAnalyser to DiskUsageAnalyzer

62. By Prabhendu V Senan

split tests into small tests

63. By Prabhendu V Senan

Recommiting

Revision history for this message
Dan Chapman  (dpniel) wrote :

Senan

so the test_window_title is still failing for me due to the locale issue with the spelling of analyser so i would just remove that and assert 'Disk Usage '.

Also when entering text you need explicitly make sure you get the text entry focus, by either clicking on it assert entry.is_focus = True and then type or you can use the focused_type context manager. e.g currenlty you have this

111 + self.create_toggle_button = self.app.select_single('GtkToggleButton',tooltip_text=u'Type a file name')
112 + self.pointing_device.move_to_object(self.create_toggle_button)
113 + self.pointing_device.click()
114 + self.keyboard.type(key_input)

Which once you have clicked the toggle button we do not actually know if the entry is now visable and has focus before typing. So after the clicking the toggle button you need to

1) assert entry.visible == True

2) either click on the entry and assert entry.is_focus == True before typing
or use the focused_type context manager (which i prefer) which looks something like

entry = self.app.select_single('GtkFileChooserEntry')
 with self.keyboard.focused_type(entry) as kb:
     kb.type(key_input)
     self.assertThat(entry.text, Equals(key_input)) (after typing assert it type correctly)
     kb.press_and_release('Enter')

3) test you have ended where you expected :-)

So anywhere in your tests you are entering text you need to do one of the above so we know the entry has focus if we can't get focus then we have a bug :-)

One last thing all boolean values your test that are using ints need to be changed for autopilot 1.4 i.e

self.assertThat(window.visible, Equals(1)) will become self.assertThat(window.visible, Equals(True)) and all 0 values become False. If you are on saucy install autopilot from the ppa:autopilot/ppa and you will get autopilot 1.4
We need to make our tests compliant with 1.4 as soon as possible.

THank you for iterating over these tests, your doing a great job and soon you will get into the swing of it, just hang in there :-)

Dan

64. By Prabhendu V Senan

added new assertion

Revision history for this message
Dan Chapman  (dpniel) wrote :

Hey senan, i'm still looking into the problems we were having last night. I am waiting on a reply from someone who may no more so as soon as hear anything we will move onwards with this. Sorry about the delay, sometimes these little niggles need sorting first :-)

Hope you are well

Dan

Revision history for this message
Prabhendu V Senan (senan) wrote :

Thanks Dan
On 22 Nov 2013 16:36, "Dan Chapman" <email address hidden> wrote:

> Hey senan, i'm still looking into the problems we were having last night.
> I am waiting on a reply from someone who may no more so as soon as hear
> anything we will move onwards with this. Sorry about the delay, sometimes
> these little niggles need sorting first :-)
>
> Hope you are well
>
> Dan
> --
>
> https://code.launchpad.net/~senan/ubuntu-autopilot-tests/DiskUsageAnalyser/+merge/193087
> You are the owner of lp:~senan/ubuntu-autopilot-tests/DiskUsageAnalyser.
>

Revision history for this message
Dan Chapman  (dpniel) wrote :

Senan hey you left too soon, ok ive been having a play and added something ive been working on for a little while (some helpful emulators :-) ), ive adapted your branch slightly here https://code.launchpad.net/~dpniel/+junk/baobab and it uses emulators for selecting items in tree so feel free to branch it have a play and see what you can come up with, take a while to look through emulators.py and see whats happening :-)

Hope this helps in the mean time till we can figure out what the difference is between desktop and sandbox

Dan

65. By Prabhendu V Senan

Fixed mouse issue

Revision history for this message
Prabhendu V Senan (senan) wrote :
Download full text (6.7 KiB)

Hi Dan,

I've made some changes to the code in order to address the
filechooserdialog treeview click issue. http://paste.ubuntu.com/6612284/ .
But I am sure its not the best way to resolve the issue. But I am still not
able to identify the treeview. Looking forward to your review comments.

On Tue, Oct 29, 2013 at 10:01 PM, Prabhendu V Senan <<email address hidden>
> wrote:

> Prabhendu V Senan has proposed merging
> lp:~senan/ubuntu-autopilot-tests/DiskUsageAnalyser into
> lp:ubuntu-autopilot-tests.
>
> Requested reviews:
> Ubuntu Testcase Admins (ubuntu-testcase)
>
> For more details, see:
>
> https://code.launchpad.net/~senan/ubuntu-autopilot-tests/DiskUsageAnalyser/+merge/193087
> --
>
> https://code.launchpad.net/~senan/ubuntu-autopilot-tests/DiskUsageAnalyser/+merge/193087
> You are the owner of lp:~senan/ubuntu-autopilot-tests/DiskUsageAnalyser.
>
> === added directory 'ubuntu_autopilot_tests/DiskUsageAnalyser'
> === added file 'ubuntu_autopilot_tests/DiskUsageAnalyser/__init__.py'
> === added file
> 'ubuntu_autopilot_tests/DiskUsageAnalyser/test_diskUsageAnalyser.py'
> --- ubuntu_autopilot_tests/DiskUsageAnalyser/test_diskUsageAnalyser.py
> 1970-01-01 00:00:00 +0000
> +++ ubuntu_autopilot_tests/DiskUsageAnalyser/test_diskUsageAnalyser.py
> 2013-10-29 16:26:36 +0000
> @@ -0,0 +1,95 @@
> +from autopilot.testcase import AutopilotTestCase
> +from autopilot.matchers import Eventually
> +from testtools.matchers import Equals, Contains, NotEquals
> +
> +from autopilot.input import Mouse, Pointer
> +
> +import os
> +from time import sleep
> +
> +class DiskUsageAnalyserTests(AutopilotTestCase):
> +
> + def setUp(self):
> + super(DiskUsageAnalyserTests,self).setUp()
> + self.app = self.launch_test_application('baobab')
> + self.mainWindowTitle = self.app.select_single('BaobabWindow')
> + self.pointing_device = Pointer(Mouse.create())
> +
> + def test_window_title(self):
> + # Verify the Disk Usage Analyzer application Title
> +
> self.assertThat(self.mainWindowTitle.title,Eventually(Contains('Disk Usage
> Analyzer')))
> +
> + def test_scan_local_folder(self):
> + self.gear_menu_option_button =
> self.app.select_single(BuilderName='menu-button')
> +
> self.pointing_device.move_to_object(self.gear_menu_option_button)
> + self.pointing_device.click()
> + self.create_scan_folder_menu_item =
> self.app.select_single('GtkModelMenuItem',action_name= 'win.scan-folder')
> +
> self.pointing_device.move_to_object(self.create_scan_folder_menu_item)
> + self.pointing_device.click()
> + self.assertThat(lambda:
> self.app.select_single('GtkFileChooserDialog').visible,Eventually(Equals(1)))
> + dialog = self.app.select_single('GtkFileChooserDialog')
> + self.assertThat(dialog.title,Eventually(Equals('Select
> Folder')))
> + tree_view = dialog.select_many('GtkTreeView')[0]
> + self.pointing_device.click_object(tree_view)
> +
> + self.create_toggle_button =
> self.app.select_single('GtkToggleButton',tooltip_text=u'Type a file name')
> +
> self.po...

Read more...

66. By Prabhendu V Senan

Fixed bug

67. By Prabhendu V Senan

fixed tree clicking

68. By senan<email address hidden>

added scan remote folder check

69. By senan<email address hidden>

refactored code

70. By senan<email address hidden>

addeded new assesrion and validations

71. By senan<email address hidden>

used index instead of menu names. fixed remote folder dialog

72. By senan<email address hidden>

removed sleep from test

73. By senan<email address hidden>

broken asserions into simple ones

74. By senan<email address hidden>

added bug number to the file

75. By senan<email address hidden>

renamed file

76. By senan<email address hidden>

added renamed file

77. By senan<email address hidden>

renamed file and folder for consistancy

78. By senan<email address hidden>

Formatted the code

79. By senan<email address hidden>

Formatted Code

80. By senan<email address hidden>

added mock

81. By senan<email address hidden>

added mock

82. By senan<email address hidden>

Added mock to create fake home directory

83. By senan<email address hidden>

added mock py2 py3 compatibility

84. By senan<email address hidden>

fixed scan_remote_folder input field issue

85. By senan<email address hidden>

added comments

86. By senan<email address hidden>

added comment for gear menu deselection

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '__init__.py'
2=== added directory 'ubuntu_autopilot_tests/DiskUsageAnalyser'
3=== added file 'ubuntu_autopilot_tests/DiskUsageAnalyser/__init__.py'
4=== added file 'ubuntu_autopilot_tests/DiskUsageAnalyser/test_diskUsageAnalyser.py'
5--- ubuntu_autopilot_tests/DiskUsageAnalyser/test_diskUsageAnalyser.py 1970-01-01 00:00:00 +0000
6+++ ubuntu_autopilot_tests/DiskUsageAnalyser/test_diskUsageAnalyser.py 2014-01-25 13:59:32 +0000
7@@ -0,0 +1,149 @@
8+from autopilot.testcase import AutopilotTestCase
9+from autopilot.matchers import Eventually
10+from testtools.matchers import Equals, Contains, NotEquals
11+from autopilot.introspection import get_proxy_object_for_existing_process
12+
13+from autopilot.input import Mouse, Pointer
14+
15+import os
16+from time import sleep
17+import subprocess
18+
19+class DiskUsageAnalyzerTests(AutopilotTestCase):
20+
21+ def setUp(self):
22+ super(DiskUsageAnalyzerTests,self).setUp()
23+ self.app = self.launch_test_application('baobab')
24+ self.mainWindowTitle = self.app.select_single('BaobabWindow')
25+ self.pointing_device = Pointer(Mouse.create())
26+
27+ def test_window_title(self):
28+ # Verify the Disk Usage Analyzer application Title
29+ self.assertThat(self.mainWindowTitle.title,Eventually(Contains('Disk Usage')))
30+
31+ def test_scan_local_folder(self):
32+ self.open_scan_folder_dialog(u'Scan Folder\u2026')
33+ self.assertThat(lambda: self.app.select_single('GtkFileChooserDialog').visible,Eventually(Equals(True)))
34+ self.open_file_chooser_dialog('/home/')
35+ self.assertThat(lambda:self.app.select_single('GdHeaderBar',BuilderName='result-header-bar').title,Eventually(Contains('home')))
36+
37+ def test_scan_remote_folder(self):
38+ #Scan remote folder--check only the UI components
39+ self.open_scan_folder_dialog(u'Scan Remote Folder\u2026')
40+ self.pointing_device.move_to_object(self.gear_menu_option_button)
41+ self.pointing_device.click()
42+ cmd_output = subprocess.Popen("ps -ef | pgrep nautilus-connect*",stdout=subprocess.PIPE, shell=True)
43+ self.connect_server_dlg_pid,error = cmd_output.communicate()
44+ self.connect_server_dlg_pid = int(self.connect_server_dlg_pid.rstrip('\n'))
45+ self.assertNotEqual(self.connect_server_dlg_pid,None)
46+ self.connect_server_dlg_proxy_object = get_proxy_object_for_existing_process(pid=self.connect_server_dlg_pid)
47+ input_server_name = self.connect_server_dlg_proxy_object.select_single('GtkEntry')
48+ with self.keyboard.focused_type(input_server_name) as kb:
49+ self.assertThat(input_server_name.is_focus,Equals(True))
50+ kb.type('smb://foo.example.org')
51+ kb.press_and_release('Delete')
52+ self.assertThat(input_server_name.text,Equals('smb://foo.example.org'))
53+ self.btn_connect = self.connect_server_dlg_proxy_object.select_single('GtkButton',label='C_onnect')
54+ self.btn_cancel = self.connect_server_dlg_proxy_object.select_single('GtkButton',label='gtk-cancel')
55+ self.assertThat(self.btn_connect.sensitive,Equals(True))
56+ self.assertThat(self.btn_cancel.sensitive,Equals(True))
57+ self.pointing_device.move_to_object(self.btn_cancel)
58+ self.pointing_device.click()
59+
60+ def test_home_list(self):
61+ #scan home folder listed in the applocations start page
62+ self.create_button_scan_home_folder = self.app.select_single('GtkLabel',label=u'<b>Home folder</b>')
63+ self.pointing_device.move_to_object(self.create_button_scan_home_folder)
64+ self.pointing_device.click()
65+ self.assertThat(lambda: self.app.select_single('GtkSpinner',BuilderName='spinner').sensitive,Eventually(Equals(True)))
66+ self.show_tree_map()
67+ self.assertThat(lambda: self.app.select_single('BaobabTreemap',BuilderName='treemap-chart').visible,Eventually(Equals(True)))
68+ self.show_ring_chart()
69+ self.assertThat(lambda: self.app.select_single('BaobabRingschart',BuilderName='rings-chart').visible,Eventually(Equals(True)))
70+
71+ def test_scan_folder_tree_map(self):
72+ self.open_scan_folder_dialog(u'Scan Folder\u2026')
73+ self.assertThat(lambda: self.app.select_single('GtkFileChooserDialog').visible,Eventually(Equals(True)))
74+ self.open_file_chooser_dialog('/home/')
75+ self.assertThat(lambda:self.app.select_single('GdHeaderBar',BuilderName='result-header-bar').title,Eventually(Contains('home')))
76+ self.show_tree_map()
77+ self.assertThat(lambda: self.app.select_single('BaobabTreemap',BuilderName='treemap-chart').visible,Eventually(Equals(1)))
78+
79+ def test_scan_folder_ring_chart(self):
80+ self.open_scan_folder_dialog(u'Scan Folder\u2026')
81+ self.assertThat(lambda: self.app.select_single('GtkFileChooserDialog').visible,Eventually(Equals(1)))
82+ self.open_file_chooser_dialog('/home/')
83+ self.assertThat(lambda:self.app.select_single('GdHeaderBar',BuilderName='result-header-bar').title,Eventually(Contains('home')))
84+ self.show_ring_chart()
85+ self.assertThat(lambda: self.app.select_single('BaobabRingschart',BuilderName='rings-chart').visible,Eventually(Equals(True)))
86+
87+ def show_tree_map(self):
88+ #Toggle treemap and ring chart
89+ self.assertThat(lambda: self.app.select_single('GtkSpinner',BuilderName='spinner').sensitive,Eventually(Equals(True)))
90+ self.tree_map_button = self.app.select_single('GtkRadioButton',BuilderName='treemap-button')
91+ self.assertThat(self.tree_map_button.sensitive,Eventually(Equals(True)))
92+ sleep(1)
93+ self.pointing_device.move_to_object(self.tree_map_button)
94+ self.pointing_device.click()
95+
96+ def show_ring_chart(self):
97+ self.assertThat(lambda: self.app.select_single('GtkSpinner',BuilderName='spinner').sensitive,Eventually(Equals(True)))
98+ self.ring_button = self.app.select_single('GtkRadioButton',BuilderName='rings-button')
99+ self.assertThat(self.ring_button.sensitive,Eventually(Equals(True)))
100+ sleep(1)
101+ self.pointing_device.move_to_object(self.ring_button)
102+ self.pointing_device.click()
103+
104+ def open_scan_folder_dialog(self,menu_item_name):
105+ self.gear_menu_option_button = self.app.select_single(BuilderName='menu-button')
106+ self.pointing_device.move_to_object(self.gear_menu_option_button)
107+ self.pointing_device.click()
108+ sleep(2)
109+ window = self.app.select_many('GtkWindowAccessible')[1]
110+ self.create_scan_folder_sub_menu_item = window.select_single('GtkCheckMenuItemAccessible', accessible_name=menu_item_name)
111+ self.assertThat(self.create_scan_folder_sub_menu_item, NotEquals(None))
112+ self.pointing_device.move_to_object(self.create_scan_folder_sub_menu_item)
113+ self.pointing_device.click()
114+
115+ def open_file_chooser_dialog(self,key_input):
116+ dialog = self.app.select_single('GtkFileChooserDialog')
117+ self.assertThat(dialog.title,Eventually(Equals('Select Folder')))
118+ places_sidebar = self.app.select_single('GtkPlacesSidebar',BuilderName=u'places_sidebar')
119+ tree_view = places_sidebar.select_single('GtkTreeView')
120+ tree_item = self.get_tree_item(tree_view,'Home')
121+ self.pointing_device.move_to_object(tree_item)
122+ self.pointing_device.click_object(tree_item)
123+
124+ self.create_toggle_button = self.app.select_single('GtkToggleButton',tooltip_text=u'Type a file name')
125+
126+ if not self.create_toggle_button.active:
127+ self.pointing_device.move_to_object(self.create_toggle_button)
128+ self.pointing_device.click()
129+ editBox = self.app.select_single('GtkFileChooserEntry')
130+ #self.keyboard.focused_type(editBox)
131+ self.assertThat(editBox.is_focus,Equals(True))
132+ self.keyboard.type(key_input)
133+ self.keyboard.press_and_release('Delete')
134+ self.assertThat(editBox.text,Equals(key_input))
135+
136+ #Open the scan directory
137+ self.open_scan_dir = self.app.select_single('GtkLabel',label='_Open')
138+ self.pointing_device.move_to_object(self.open_scan_dir)
139+ self.pointing_device.click()
140+
141+ def get_tree_item(self, treeview_object, item_label):
142+ """ Gets an item from a gtktreeview
143+ param treeview_object: a selected GtkTreeView object
144+ param item_label: Visual label value of the tree item i.e 'Documents'
145+ returns treeview item object"""
146+ #get all accessible treeviews
147+ accessible_treeviews = self.app.select_many('GtkTreeViewAccessible')
148+ # find the one that has the same globalRect as treeview_object
149+ for treeview_accessible in accessible_treeviews:
150+ if treeview_accessible.globalRect == treeview_object.globalRect:
151+ #select our item from here
152+ tree_item = treeview_accessible.select_many('GtkTextCellAccessible',accessible_name=item_label)
153+ return tree_item[1]
154+
155+
156+

Subscribers

People subscribed via source and target branches