auto_test 0.1.9.8.7 → 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +5 -4
- data/lib/authentication.rb +32 -14
- data/lib/auto_test.rb +3 -4
- data/lib/auto_test/railtie.rb +1 -0
- data/lib/auto_test/version.rb +1 -1
- data/lib/dsl.rb +10 -1
- data/lib/error.rb +9 -1
- data/lib/page.rb +17 -2
- data/lib/spec/requests/auto_spec.rb +3 -0
- data/lib/spec/requests/error_reduction_spec.rb +376 -361
- data/lib/spec/requests/simulation_spec.rb +20 -1
- data/lib/tasks/auto_test.rb +3 -3
- data/lib/test.rb +92 -39
- data/lib/test_starter.rb +8 -0
- metadata +2 -2
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# AutoTest
|
2
2
|
|
3
|
-
|
3
|
+
This Gem tests your application automatically. With some configuration it will login and logout, click links, fill in forms
|
4
|
+
and find exceptions. After finding an exception it will reduce the path to this error and show you the reduced path in a
|
5
|
+
firefox browser.
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -18,12 +20,11 @@ Or install it yourself as:
|
|
18
20
|
|
19
21
|
## Usage
|
20
22
|
|
21
|
-
TODO: Write usage instructions here
|
22
23
|
|
23
24
|
## Contributing
|
24
25
|
|
25
|
-
1. Fork it
|
26
|
+
<!-- 1. Fork it
|
26
27
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
28
|
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
29
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
30
|
+
5. Create new Pull Request -->
|
data/lib/authentication.rb
CHANGED
@@ -1,25 +1,32 @@
|
|
1
1
|
require 'capybara/rspec'
|
2
2
|
|
3
3
|
module AutoTest
|
4
|
+
# This module deals with all functions concerning authentication of users in the application
|
4
5
|
module Authentication
|
5
6
|
module_function
|
6
7
|
|
7
|
-
# initialize the
|
8
|
+
# initialize the users array
|
8
9
|
def init_users
|
9
10
|
@users = []
|
10
11
|
@db_users = [false, nil]
|
11
12
|
end
|
12
|
-
|
13
|
-
|
13
|
+
|
14
|
+
# initialize login data array
|
15
|
+
def init_login_data
|
16
|
+
@data = []
|
17
|
+
end
|
18
|
+
|
19
|
+
# user function to set the logout path
|
14
20
|
def set_logout_path(path)
|
15
21
|
@logout = path
|
16
22
|
end
|
17
23
|
|
24
|
+
# getter for logout path
|
18
25
|
def get_logout_path
|
19
26
|
@logout
|
20
27
|
end
|
21
28
|
|
22
|
-
# set the attribute_names and fields that are needed to login
|
29
|
+
# user function to set the attribute_names and fields that are needed to login
|
23
30
|
# the argument are two arrays, the first are the database names of the attribute
|
24
31
|
# the second are the belonging field names
|
25
32
|
def set_login_attribute_names(names, fields)
|
@@ -36,34 +43,34 @@ module AutoTest
|
|
36
43
|
@login
|
37
44
|
end
|
38
45
|
|
39
|
-
# set the login path
|
46
|
+
# user function to set the login path
|
40
47
|
def set_login_path(path)
|
41
48
|
@login = path
|
42
49
|
end
|
43
|
-
|
50
|
+
|
51
|
+
# user function to set the text of the login button
|
44
52
|
def set_login_button(text)
|
45
53
|
@login_button = text
|
46
54
|
end
|
47
55
|
|
56
|
+
# get the login button
|
48
57
|
def get_login_button
|
49
58
|
@login_button
|
50
59
|
end
|
51
60
|
|
52
|
-
|
53
|
-
@data = []
|
54
|
-
end
|
55
|
-
|
61
|
+
# get login data array
|
56
62
|
def get_login_data
|
57
63
|
@data
|
58
64
|
end
|
59
65
|
|
66
|
+
# user function to set the login data
|
60
67
|
def set_login_data(*data)
|
61
68
|
data.each do |d|
|
62
69
|
@data << d
|
63
70
|
end
|
64
|
-
|
65
71
|
end
|
66
72
|
|
73
|
+
# user function to determine if users are read from db
|
67
74
|
def get_users_from_db(user_class_name, bool)
|
68
75
|
@users = user_class_name.find(:all)
|
69
76
|
if bool then
|
@@ -73,35 +80,42 @@ module AutoTest
|
|
73
80
|
end
|
74
81
|
end
|
75
82
|
|
83
|
+
# user function to set login names
|
76
84
|
def set_login_names(names)
|
77
85
|
@names = names
|
78
86
|
end
|
79
87
|
|
88
|
+
# get login names
|
80
89
|
def get_login_names
|
81
90
|
@names
|
82
91
|
end
|
83
92
|
|
84
|
-
|
93
|
+
# user function to set login fields
|
85
94
|
def set_login_fields(fields)
|
86
95
|
@fields = fields
|
87
96
|
end
|
88
97
|
|
98
|
+
#get login fields
|
89
99
|
def get_login_fields
|
90
100
|
@fields
|
91
101
|
end
|
92
102
|
|
103
|
+
# user function to set unique attribute name
|
93
104
|
def set_unique_login_attribute_name(name)
|
94
105
|
@unique_login = name
|
95
106
|
end
|
96
107
|
|
108
|
+
# get unique attribute name
|
97
109
|
def get_unique_login_attribute_name
|
98
110
|
@unique_login
|
99
111
|
end
|
100
112
|
|
113
|
+
# get first element of db users, determine if users are read from db
|
101
114
|
def use_db_users
|
102
115
|
@db_users[0]
|
103
116
|
end
|
104
117
|
|
118
|
+
# get second element of db users, the class of the user
|
105
119
|
def user_class
|
106
120
|
@db_users[1]
|
107
121
|
end
|
@@ -124,20 +138,23 @@ module AutoTest
|
|
124
138
|
return @users
|
125
139
|
end
|
126
140
|
|
141
|
+
# set user data
|
127
142
|
def set_user_data(value)
|
128
143
|
@user_data = value
|
129
144
|
end
|
130
145
|
|
146
|
+
# get user data
|
131
147
|
def get_user_data
|
132
148
|
@user_data
|
133
149
|
end
|
134
150
|
|
135
|
-
|
151
|
+
# logout a user
|
136
152
|
def logout(session)
|
137
153
|
begin
|
138
154
|
hash = Hash.new
|
139
155
|
hash["#{Test.get_sessions_array.index(session)}:#{session.current_path}"] = get_logout_path
|
140
156
|
Test.add_to_action_path hash
|
157
|
+
# logout the user by visiting the logout path
|
141
158
|
session.visit get_logout_path
|
142
159
|
Page.check_for_error_code(session)
|
143
160
|
rescue => e
|
@@ -161,6 +178,7 @@ module AutoTest
|
|
161
178
|
end
|
162
179
|
end
|
163
180
|
end
|
181
|
+
# fill in fields with user data, either from db or given by the tester
|
164
182
|
if @db_users[0] then
|
165
183
|
get_login_attributes.each do |field|
|
166
184
|
session.fill_in field[1], :with => user.send(field[0].to_sym)
|
@@ -171,8 +189,8 @@ module AutoTest
|
|
171
189
|
end
|
172
190
|
end
|
173
191
|
session.click_button get_login_button
|
174
|
-
|
175
192
|
Page.check_for_error_code(session)
|
193
|
+
# save from exception if user object has changed
|
176
194
|
rescue (ActiveRecord::RecordNotFound)
|
177
195
|
Test.sessions(Test.get_sessions_array.index(session), "depth", Test.get_max_depth+1)
|
178
196
|
Test.sessions(Test.get_sessions_array.index(session), "current_depth", Test.get_sessions(Test.get_sessions_array.index(session), "depth"))
|
data/lib/auto_test.rb
CHANGED
@@ -9,7 +9,7 @@ def logger
|
|
9
9
|
Rails.logger
|
10
10
|
end
|
11
11
|
|
12
|
-
|
12
|
+
# Main module
|
13
13
|
module AutoTest
|
14
14
|
include Page
|
15
15
|
include Error
|
@@ -28,8 +28,6 @@ module AutoTest
|
|
28
28
|
yield(configuration)
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
31
|
class Configuration
|
34
32
|
def initialize
|
35
33
|
Test.initialize_test
|
@@ -39,11 +37,12 @@ module AutoTest
|
|
39
37
|
DatabaseCleaner.clean
|
40
38
|
end
|
41
39
|
|
40
|
+
# define all user functions
|
41
|
+
|
42
42
|
def use_fixtures(bool)
|
43
43
|
Test.use_fixtures(bool)
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
46
|
def fixtures(*fixtures)
|
48
47
|
Test.fixtures(fixtures)
|
49
48
|
end
|
data/lib/auto_test/railtie.rb
CHANGED
data/lib/auto_test/version.rb
CHANGED
data/lib/dsl.rb
CHANGED
@@ -20,6 +20,7 @@ module AutoTest
|
|
20
20
|
Test.set_max_depth(value)
|
21
21
|
end
|
22
22
|
|
23
|
+
# set the unique attribute name of the user
|
23
24
|
def set_unique_login_attribute_name(name)
|
24
25
|
Authentication.set_unique_login_attribute_name(name)
|
25
26
|
end
|
@@ -37,6 +38,7 @@ module AutoTest
|
|
37
38
|
Authentication.set_login_data(*data)
|
38
39
|
end
|
39
40
|
|
41
|
+
# determine wether users can be read from db or not
|
40
42
|
def get_users_from_db(user_class_name, bool)
|
41
43
|
Authentication.get_users_from_db(user_class_name, bool)
|
42
44
|
end
|
@@ -47,19 +49,23 @@ module AutoTest
|
|
47
49
|
Test.set_object_dependency(child, parent, attribute_name)
|
48
50
|
end
|
49
51
|
|
52
|
+
# set the number of sessions used to test the app
|
50
53
|
def set_number_of_sessions(number)
|
51
54
|
Test.set_number_of_sessions(number)
|
52
55
|
end
|
53
56
|
|
57
|
+
# set the maxium number of links one session can click in a row before
|
58
|
+
# the next session continues
|
54
59
|
def set_max_number_of_session_links(no)
|
55
60
|
Test.set_max_number_of_session_links(no)
|
56
61
|
end
|
57
62
|
|
58
|
-
|
63
|
+
# set, if there´s no authentication in the application
|
59
64
|
def set_no_auth
|
60
65
|
Test.set_no_auth
|
61
66
|
end
|
62
67
|
|
68
|
+
# set the text of the login button
|
63
69
|
def set_login_button(text)
|
64
70
|
Authentication.set_login_button(text)
|
65
71
|
end
|
@@ -77,14 +83,17 @@ module AutoTest
|
|
77
83
|
Authentication.set_login_names(names)
|
78
84
|
end
|
79
85
|
|
86
|
+
# set the path to logout
|
80
87
|
def set_logout_path(path)
|
81
88
|
Authentication.set_logout_path(path)
|
82
89
|
end
|
83
90
|
|
91
|
+
# determine if the test is supposed to stop when the first error is found
|
84
92
|
def stop_at_first_error(stop_at_first_error)
|
85
93
|
Test.stop_at_first_error(stop_at_first_error)
|
86
94
|
end
|
87
95
|
|
96
|
+
# set the number of test runs
|
88
97
|
def set_number_of_test_runs(number)
|
89
98
|
Test.set_number_of_test_runs(number)
|
90
99
|
end
|
data/lib/error.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'capybara/rspec'
|
2
2
|
|
3
3
|
module AutoTest
|
4
|
+
|
5
|
+
# This module deals with all functions concerning errors
|
4
6
|
module Error
|
5
7
|
module_function
|
8
|
+
|
6
9
|
# increment the errorcount in the first field of the array,
|
7
10
|
# add error messages
|
8
11
|
def inc_error(value)
|
@@ -15,6 +18,8 @@ module AutoTest
|
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
21
|
+
# print the error on the console
|
22
|
+
# just the message of the exception, no backtrace
|
18
23
|
def print_errors
|
19
24
|
if get_error > 0 then
|
20
25
|
if get_error == 1 then
|
@@ -33,14 +38,17 @@ module AutoTest
|
|
33
38
|
end
|
34
39
|
end
|
35
40
|
|
41
|
+
# get the error count
|
36
42
|
def get_error
|
37
43
|
@error[0]
|
38
44
|
end
|
39
|
-
|
45
|
+
|
46
|
+
# get error message
|
40
47
|
def get_error_messages
|
41
48
|
@error[1..@error.size-1]
|
42
49
|
end
|
43
50
|
|
51
|
+
# init error count with 0
|
44
52
|
def init_error
|
45
53
|
@error = [0]
|
46
54
|
end
|
data/lib/page.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'capybara/rspec'
|
3
|
-
|
3
|
+
# get a random time
|
4
4
|
class Time
|
5
5
|
def self.random
|
6
6
|
year = Time.now.year
|
@@ -11,6 +11,7 @@ class Time
|
|
11
11
|
end
|
12
12
|
|
13
13
|
module AutoTest
|
14
|
+
# This module deals with the interaction on the page like clicking links and filling in forms
|
14
15
|
module Page
|
15
16
|
module_function
|
16
17
|
|
@@ -22,6 +23,7 @@ module AutoTest
|
|
22
23
|
if Test.get_sessions(i,"depth") <= Test.get_max_depth then
|
23
24
|
if Test.get_sessions(i,"iteration") <= Test.get_sessions(i,"iterations") then
|
24
25
|
begin
|
26
|
+
# Login
|
25
27
|
if Test.get_sessions(i, "current_depth") == 0 && !Test.no_auth then
|
26
28
|
Authentication.login(Test.get_sessions(i,"user"),session)
|
27
29
|
Test.check_invariants
|
@@ -30,6 +32,7 @@ module AutoTest
|
|
30
32
|
session.visit "/"
|
31
33
|
end
|
32
34
|
if (Test.get_sessions(i,"current_depth") < Test.get_sessions(i,"depth")) then
|
35
|
+
# get the links of the page and delete the ones the tester specified
|
33
36
|
links = all_links(session)
|
34
37
|
handle_excluded_links(links)
|
35
38
|
if !links.empty? then
|
@@ -38,13 +41,17 @@ module AutoTest
|
|
38
41
|
paths = Test.get_sessions(i,"paths")
|
39
42
|
paths[path] = links.size
|
40
43
|
Test.sessions(i, "paths", paths)
|
44
|
+
# choose a random link
|
41
45
|
random_link = links[rand(links.size)]
|
46
|
+
# check for javascript
|
42
47
|
if random_link[:href] != "#" then
|
43
48
|
hash = Hash.new
|
44
49
|
hash["#{i}:#{path}"] = random_link[:href]+"+++"+random_link.text
|
45
50
|
Test.add_to_action_path hash
|
46
51
|
end
|
52
|
+
# click the link
|
47
53
|
random_link.click
|
54
|
+
# update the console output
|
48
55
|
STDOUT.write("\r#{Test.run}. run: \t#{Test.link_counter} links clicked, \t#{Test.users_logged_in} users logged in, \t#{Error.get_error} Errors")
|
49
56
|
Test.link_counter = Test.link_counter + 1
|
50
57
|
Test.check_invariants
|
@@ -55,19 +62,23 @@ module AutoTest
|
|
55
62
|
else
|
56
63
|
links = all_links(session)
|
57
64
|
handle_excluded_links(links)
|
65
|
+
# calculate new iterations number
|
58
66
|
if !links.empty? then
|
59
67
|
Test.sessions(i,"iterations", 0)
|
60
68
|
Test.get_sessions(i,"paths").each do |key, value|
|
61
69
|
Test.sessions(i,"iterations", Test.get_sessions(i, "iterations") + value)
|
62
70
|
end
|
63
71
|
end
|
72
|
+
# logouz
|
64
73
|
if !Test.no_auth then
|
65
74
|
Authentication.logout(session)
|
66
75
|
end
|
76
|
+
# new initialization of session variables
|
67
77
|
Test.sessions(i, "current_depth", 0)
|
68
78
|
Test.sessions(i, "paths", Hash.new)
|
69
79
|
Test.sessions(i, "iteration", Test.get_sessions(i, "iteration") + 1)
|
70
80
|
end
|
81
|
+
# rescue from exceptions, process the error
|
71
82
|
rescue => e
|
72
83
|
if Test.stop_at_first_error? then Test.stop! end
|
73
84
|
message = e.message.to_s + " :" + e.backtrace.first.to_s
|
@@ -76,6 +87,7 @@ module AutoTest
|
|
76
87
|
|
77
88
|
end
|
78
89
|
else
|
90
|
+
# new initialization of session variables
|
79
91
|
Test.sessions(i, "iteration", 0)
|
80
92
|
Test.sessions(i, "iterations", 0)
|
81
93
|
Test.sessions(i, "depth", Test.get_sessions(i, "depth") + 1)
|
@@ -86,6 +98,7 @@ module AutoTest
|
|
86
98
|
Test.users_logged_in = Test.users_logged_in + 1
|
87
99
|
end
|
88
100
|
if !Test.no_auth then
|
101
|
+
# get new random user for next round
|
89
102
|
Test.sessions(i, "current_user", Test.get_sessions(i,"current_user")+1)
|
90
103
|
user = Authentication.get_users[rand(Authentication.get_users.size)]
|
91
104
|
Test.sessions(i, "user", user)
|
@@ -113,9 +126,11 @@ module AutoTest
|
|
113
126
|
button = all_submits(session)[rand(all_submits(session).size)]
|
114
127
|
selects = all_selects(session)
|
115
128
|
texts = []
|
129
|
+
# handle select fields first
|
116
130
|
selects.each do |s|
|
117
131
|
select_option(s[:id], texts, session)
|
118
132
|
end
|
133
|
+
# handle other input types
|
119
134
|
inputs.each do |i|
|
120
135
|
case i[:type]
|
121
136
|
when "email" then
|
@@ -147,6 +162,7 @@ module AutoTest
|
|
147
162
|
end
|
148
163
|
text = ""
|
149
164
|
end
|
165
|
+
# check for values given by the tester and set these
|
150
166
|
inputs_to_set = Test.get_inputs
|
151
167
|
if !inputs_to_set.empty? then
|
152
168
|
inputs.each do |i|
|
@@ -163,7 +179,6 @@ module AutoTest
|
|
163
179
|
Test.add_to_action_path hash
|
164
180
|
session.click_button button.value
|
165
181
|
Test.link_counter = Test.link_counter + 1
|
166
|
-
|
167
182
|
check_for_error_code(session)
|
168
183
|
end
|
169
184
|
|
@@ -10,12 +10,15 @@ require 'test_starter'
|
|
10
10
|
describe "Application" do
|
11
11
|
|
12
12
|
describe "auto_test" do
|
13
|
+
# load fixtures
|
13
14
|
if AutoTest::Test.use_fixtures? then
|
14
15
|
fixtures(*AutoTest::Test.get_fixtures)
|
15
16
|
end
|
16
17
|
it "does test the application automatically" do
|
18
|
+
# load test data
|
17
19
|
load "#{Rails.root}/db/test_seeds.rb"
|
18
20
|
t = TestStarter.new
|
21
|
+
# start the test
|
19
22
|
t.test
|
20
23
|
end
|
21
24
|
end
|