rubotium 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +24 -0
- data/Rakefile +1 -0
- data/bin/rubotium +26 -0
- data/lib/rubotium/adb/command.rb +21 -0
- data/lib/rubotium/adb/devices.rb +25 -0
- data/lib/rubotium/adb/install_command.rb +17 -0
- data/lib/rubotium/adb/instrumentation.rb +36 -0
- data/lib/rubotium/adb/shell.rb +30 -0
- data/lib/rubotium/adb/test_result_parser.rb +87 -0
- data/lib/rubotium/adb/uninstall_command.rb +17 -0
- data/lib/rubotium/adb.rb +13 -0
- data/lib/rubotium/apk/converter.rb +22 -0
- data/lib/rubotium/apk.rb +7 -0
- data/lib/rubotium/cmd.rb +17 -0
- data/lib/rubotium/device.rb +49 -0
- data/lib/rubotium/devices.rb +25 -0
- data/lib/rubotium/formatters/junit_formatter.rb +82 -0
- data/lib/rubotium/grouper.rb +40 -0
- data/lib/rubotium/jar_reader.rb +70 -0
- data/lib/rubotium/package.rb +36 -0
- data/lib/rubotium/runable_test.rb +11 -0
- data/lib/rubotium/test_case.rb +6 -0
- data/lib/rubotium/test_suite.rb +12 -0
- data/lib/rubotium/version.rb +3 -0
- data/lib/rubotium.rb +85 -0
- data/rubotium.gemspec +33 -0
- data/spec/fixtures/adb_devices_results.rb +23 -0
- data/spec/fixtures/adb_results.rb +60 -0
- data/spec/fixtures/jar_contents.rb +28 -0
- data/spec/fixtures/javap_classes.rb +52 -0
- data/spec/lib/rubotium/adb/adb_devices_spec.rb +25 -0
- data/spec/lib/rubotium/adb/adb_instrumentation_spec.rb +32 -0
- data/spec/lib/rubotium/adb/adb_result_parser_spec.rb +132 -0
- data/spec/lib/rubotium/adb/adb_shell_spec.rb +23 -0
- data/spec/lib/rubotium/devices_spec.rb +45 -0
- data/spec/lib/rubotium/formatters/junit_formatter_spec.rb +7 -0
- data/spec/lib/rubotium/grouper_spec.rb +56 -0
- data/spec/lib/rubotium/jar_reader_spec.rb +58 -0
- data/spec/lib/rubotium_spec.rb +13 -0
- data/spec/spec_helper.rb +20 -0
- metadata +256 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'android_apk'
|
2
|
+
|
3
|
+
module Rubotium
|
4
|
+
class Package
|
5
|
+
def initialize(package_path)
|
6
|
+
@package_path = package_path
|
7
|
+
end
|
8
|
+
|
9
|
+
def valid?
|
10
|
+
!analyzed_package.nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
def name
|
14
|
+
analyzed_package.package_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def path
|
18
|
+
package_path
|
19
|
+
end
|
20
|
+
|
21
|
+
def version_name
|
22
|
+
analyzed_package.version_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def version_code
|
26
|
+
analyzed_package.version_code
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
attr_reader :package_path
|
31
|
+
|
32
|
+
def analyzed_package
|
33
|
+
@analyzed_package ||= AndroidApk.analyze(package_path)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/rubotium.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rubotium/version'
|
2
|
+
require 'rubotium/jar_reader'
|
3
|
+
require 'rubotium/adb'
|
4
|
+
require 'rubotium/apk'
|
5
|
+
require 'rubotium/cmd'
|
6
|
+
require 'rubotium/device'
|
7
|
+
require 'rubotium/devices'
|
8
|
+
require 'rubotium/formatters/junit_formatter'
|
9
|
+
require 'rubotium/grouper'
|
10
|
+
require 'rubotium/test_case'
|
11
|
+
require 'rubotium/test_suite'
|
12
|
+
require 'rubotium/runable_test'
|
13
|
+
require 'rubotium/package'
|
14
|
+
|
15
|
+
require 'parallel'
|
16
|
+
module Rubotium
|
17
|
+
class Error < StandardError; end
|
18
|
+
|
19
|
+
class NoDevicesError < Error; end
|
20
|
+
|
21
|
+
class NoMatchedDevicesError < Error; end
|
22
|
+
|
23
|
+
class NoTestSuiteError < Error; end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def new(opts = {})
|
27
|
+
raise RuntimeError, "Empty configuration" if opts.empty?
|
28
|
+
startTime = Time.now
|
29
|
+
application_package = Rubotium::Package.new(opts[:app_apk_path])
|
30
|
+
tests_package = Rubotium::Package.new(opts[:tests_apk_path])
|
31
|
+
test_runner = opts[:runner]
|
32
|
+
|
33
|
+
if (opts[:tests_jar_path])
|
34
|
+
test_suites = JarReader.new(opts[:tests_jar_path]).get_tests
|
35
|
+
else
|
36
|
+
path_to_jar = File.join(Dir.mktmpdir, 'tests.jar')
|
37
|
+
begin
|
38
|
+
puts("Convertig dex to jar")
|
39
|
+
Rubotium::Apk::Converter.new(tests_package.path, path_to_jar).convert_to_jar
|
40
|
+
puts("Reading jar content")
|
41
|
+
test_suites = jar_reader = JarReader.new(path_to_jar).get_tests
|
42
|
+
ensure
|
43
|
+
FileUtils.remove_entry(path_to_jar)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
tests_count = 0
|
48
|
+
test_suites.each{|test_suite|
|
49
|
+
tests_count = tests_count + test_suite.test_cases.count
|
50
|
+
}
|
51
|
+
|
52
|
+
puts "There are #{test_suites.count} packages with tests in the Jar file"
|
53
|
+
puts "#{tests_count} tests to run"
|
54
|
+
|
55
|
+
devices = Devices.new(opts[:device_matcher]).all
|
56
|
+
test_suites = Grouper.new(test_suites, devices.count).create_groups
|
57
|
+
|
58
|
+
devices.each{|device|
|
59
|
+
device.uninstall application_package.name
|
60
|
+
device.install application_package.path
|
61
|
+
} if application_package.valid?
|
62
|
+
|
63
|
+
devices.each{|device|
|
64
|
+
device.uninstall tests_package.name
|
65
|
+
device.install tests_package.path
|
66
|
+
} if tests_package.valid?
|
67
|
+
|
68
|
+
devices.each_with_index{|device, index|
|
69
|
+
device.test_package_name = tests_package.name
|
70
|
+
device.test_runner_name = test_runner || "android.test.InstrumentationTestRunner"
|
71
|
+
device.testsuite = test_suites[index]
|
72
|
+
}
|
73
|
+
|
74
|
+
devices = Parallel.map(devices, :in_processes=> devices.count) {|device|
|
75
|
+
device.run_tests
|
76
|
+
device
|
77
|
+
}
|
78
|
+
|
79
|
+
puts "Tests took: #{Time.at(Time.now-startTime).utc.strftime("%H:%M:%S")}"
|
80
|
+
devices.each{|device|
|
81
|
+
Formatters::JunitFormatter.new(device.results, "#{device.serial}_#{opts[:report]}")
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/rubotium.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rubotium/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rubotium"
|
8
|
+
spec.version = Rubotium::VERSION
|
9
|
+
spec.authors = ["Slawomir Smiechura"]
|
10
|
+
spec.email = ["ssmiech@gmail.com"]
|
11
|
+
spec.summary = "Run your Robotium tests with ease"
|
12
|
+
spec.description = "This gem allows to run Robotium tests in parallel on multiple devices"
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "simplecov", "0.8.2"
|
23
|
+
spec.add_development_dependency "coveralls", "0.7.0"
|
24
|
+
spec.add_development_dependency "rspec", "2.14.1"
|
25
|
+
spec.add_development_dependency "rspec-mocks"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
|
28
|
+
spec.add_dependency 'builder', '3.2.2'
|
29
|
+
spec.add_dependency 'trollop', '2.0'
|
30
|
+
spec.add_dependency 'parallel', '0.9.2'
|
31
|
+
spec.add_dependency 'dex2jar', '0.0.6'
|
32
|
+
spec.add_dependency 'android_apk', '0.7.0'
|
33
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Fixtures
|
2
|
+
class Adb
|
3
|
+
module Devices
|
4
|
+
class << self
|
5
|
+
def two_devices_attached_one_is_offline
|
6
|
+
"List of devices attached \nemulator-5554\toffline\nemulator-5556\tdevice\n\n"
|
7
|
+
end
|
8
|
+
|
9
|
+
def two_devices_attached
|
10
|
+
"List of devices attached \nemulator-5554\tdevice\nemulator-5556\tdevice\n\n"
|
11
|
+
end
|
12
|
+
|
13
|
+
def one_device_offline
|
14
|
+
"List of devices attached \nemulator-5554\toffline\n\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
def one_device
|
18
|
+
"List of devices attached \nemulator-5554\tdevice\n\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Fixtures
|
2
|
+
class Adb
|
3
|
+
class << self
|
4
|
+
def test_success
|
5
|
+
"\r\ncom.android.activity.resolve.facebook.ResolveTrackDeeplink:.\
|
6
|
+
\r\nTest results for RandomizingRunner=.\
|
7
|
+
\r\nTime: 5.873\
|
8
|
+
\r\n\r\nOK (1 test)\
|
9
|
+
\r\n\r\n\r\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_failure
|
13
|
+
"\r\ncom.android.activity.resolve.facebook.ResolveTrackDeeplink:\r\nFailure in testFacebookTrackDeeplink:\r\njunit.framework.ComparisonFailure: expected:<...h other on SoundClou[]> but was:<...h other on SoundClou[d]>\r\n\tat com.android.activity.resolve.facebook.ResolveTrackDeeplink.testFacebookTrackDeeplink(ResolveTrackDeeplink.java:22)\r\n\tat java.lang.reflect.Method.invokeNative(Native Method)\r\n\tat android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)\r\n\tat android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)\r\n\tat android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)\r\n\tat com.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:91)\r\n\tat android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)\r\n\tat android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)\r\n\tat android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)\r\n\tat com.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)\r\n\tat android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)\r\n\r\nTest results for RandomizingRunner=.F\r\nTime: 6.485\r\n\r\nFAILURES!!!\r\nTests run: 1, Failures: 1, Errors: 0\r\n\r\n\r\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_error
|
17
|
+
"\r\ncom.android.activity.resolve.facebook.ResolveTrackDeeplink:\r\nError in testFacebookTrackDeeplink:\r\njava.lang.NullPointerException\r\n\tat com.android.activity.resolve.facebook.ResolveTrackDeeplink.testFacebookTrackDeeplink(ResolveTrackDeeplink.java:22)\r\n\tat java.lang.reflect.Method.invokeNative(Native Method)\r\n\tat android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)\r\n\tat android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)\r\n\tat android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)\r\n\tat com.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:91)\r\n\tat android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)\r\n\tat android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)\r\n\tat android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)\r\n\tat com.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)\r\n\tat android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)\r\n\r\nTest results for RandomizingRunner=.E\r\nTime: 4.314\r\n\r\nFAILURES!!!\r\nTests run: 1, Failures: 0, Errors: 1\r\n\r\n\r\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_run_error
|
21
|
+
"\r\ncom.android.search.Search:INSTRUMENTATION_RESULT: shortMsg=java.lang.NullPointerException\
|
22
|
+
\r\nINSTRUMENTATION_RESULT: longMsg=java.lang.NullPointerException: An error occured while executing doInBackground()\
|
23
|
+
\r\nINSTRUMENTATION_CODE: 0\r\n"
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_cannot_start_error
|
27
|
+
"INSTRUMENTATION_STATUS: id=ActivityManagerService\
|
28
|
+
\r\nINSTRUMENTATION_STATUS: Error=Unable to find instrumentation info for: ComponentInfo{com.android.tests/com.android.tests.RandomizingRunner}\
|
29
|
+
\r\nINSTRUMENTATION_STATUS_CODE: -1\
|
30
|
+
\\r\nandroid.util.AndroidException: INSTRUMENTATION_FAILED: com.android.tests/com.android.tests.RandomizingRunner\
|
31
|
+
\r\n\tat com.android.commands.am.Am.runInstrument(Am.java:616)\
|
32
|
+
\r\n\tat com.android.commands.am.Am.run(Am.java:118)\
|
33
|
+
\r\n\tat com.android.commands.am.Am.main(Am.java:81)\
|
34
|
+
\r\n\tat com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)\
|
35
|
+
\r\n\tat com.android.internal.os.RuntimeInit.main(RuntimeInit.java:235)\
|
36
|
+
\r\n\tat dalvik.system.NativeStart.main(Native Method)\r\n"
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_failure_stack_trace
|
40
|
+
"junit.framework.ComparisonFailure: expected:<...h other on SoundClou[]> but was:<...h other on SoundClou[d]>\r\n\tat com.android.activity.resolve.facebook.ResolveTrackDeeplink.testFacebookTrackDeeplink(ResolveTrackDeeplink.java:22)\r\n\tat java.lang.reflect.Method.invokeNative(Native Method)\r\n\tat android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)\r\n\tat android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)\r\n\tat android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)\r\n\tat com.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:91)\r\n\tat android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)\r\n\tat android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)\r\n\tat android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)\r\n\tat com.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)\r\n\tat android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)"
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_error_stack_trace
|
44
|
+
"java.lang.NullPointerException\r\n\tat com.android.activity.resolve.facebook.ResolveTrackDeeplink.testFacebookTrackDeeplink(ResolveTrackDeeplink.java:22)\r\n\tat java.lang.reflect.Method.invokeNative(Native Method)\r\n\tat android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)\r\n\tat android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)\r\n\tat android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)\r\n\tat com.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:91)\r\n\tat android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)\r\n\tat android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)\r\n\tat android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)\r\n\tat com.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)\r\n\tat android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)"
|
45
|
+
end
|
46
|
+
|
47
|
+
def error_message
|
48
|
+
"java.lang.NullPointerException: An error occured while executing doInBackground()"
|
49
|
+
end
|
50
|
+
|
51
|
+
def passed_negative_time
|
52
|
+
"\r\ncom.android.explore.ExploreRecommendations:.\r\nTest results for RandomizingRunner=.\r\nTime: -53.656\r\n\r\nOK (1 test)\r\n\r\n\r\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
def system_crash
|
56
|
+
"\r\ncom.android.player.Player:INSTRUMENTATION_ABORTED: System has crashed.\r\n"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Fixtures
|
2
|
+
module JarContents
|
3
|
+
class << self
|
4
|
+
def duplicated_classes
|
5
|
+
<<-JAR_CONTENT
|
6
|
+
com/android/tests/Waiter$1$1.class
|
7
|
+
com/android/tests/Waiter$1.class
|
8
|
+
com/android/tests/Waiter$2.class
|
9
|
+
com/android/tests/Waiter$ByClassCondition.class
|
10
|
+
com/android/tests/Waiter$DrawerStateCondition.class
|
11
|
+
com/android/tests/Waiter$NoProgressBarCondition.class
|
12
|
+
com/android/tests/Waiter$NoTextCondition.class
|
13
|
+
com/android/tests/Waiter$PlayerPlayingCondition.class
|
14
|
+
com/android/tests/Waiter$VisibleElementCondition.class
|
15
|
+
com/android/tests/Waiter.class
|
16
|
+
JAR_CONTENT
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.multiple_classes
|
22
|
+
<<-JAR_CONTENT
|
23
|
+
com/android/screens/HomeScreen.class
|
24
|
+
com/android/auth/login/LoginFlowTest.class
|
25
|
+
JAR_CONTENT
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Fixtures
|
2
|
+
module JavaPClasses
|
3
|
+
class << self
|
4
|
+
def class_with_no_tests
|
5
|
+
<<-JAVAP
|
6
|
+
public class com.android.tests.Waiter extends java.lang.Object{
|
7
|
+
public final int NETWORK_TIMEOUT;
|
8
|
+
public final int TIMEOUT;
|
9
|
+
public com.android.tests.Han solo;
|
10
|
+
static {};
|
11
|
+
public com.android.tests.Waiter(com.android.tests.Han);
|
12
|
+
static java.lang.String access$300();
|
13
|
+
public void waitForActivity(java.lang.Class);
|
14
|
+
public boolean waitForContentAndRetryIfLoadingFailed();
|
15
|
+
public boolean waitForDrawerToClose();
|
16
|
+
public boolean waitForDrawerToOpen();
|
17
|
+
public boolean waitForElement(int);
|
18
|
+
public boolean waitForElement(android.view.View);
|
19
|
+
public boolean waitForElement(java.lang.Class);
|
20
|
+
public boolean waitForFragmentByTag(java.lang.String);
|
21
|
+
public boolean waitForItemCountToIncrease(android.widget.ListAdapter, int);
|
22
|
+
public void waitForLogInDialog();
|
23
|
+
public boolean waitForPlayerPlaying();
|
24
|
+
public void waitForText(java.lang.String);
|
25
|
+
public boolean waitForTextToDisappear(java.lang.String);
|
26
|
+
public void waitForViewId(int);
|
27
|
+
public boolean waitForWebViewToLoad(android.webkit.WebView);
|
28
|
+
}
|
29
|
+
JAVAP
|
30
|
+
end
|
31
|
+
|
32
|
+
def class_with_tests
|
33
|
+
<<-JAVAP
|
34
|
+
public class com.android.auth.login.LoginFlowTest extends com.android.auth.LoginTestCase{
|
35
|
+
public com.android.auth.login.LoginFlowTest();
|
36
|
+
public void ignore_testLoginWithFBApplication();
|
37
|
+
public void setUp() throws java.lang.Exception;
|
38
|
+
public void testGPlusLoginFlow();
|
39
|
+
public void testLoginAndLogout();
|
40
|
+
public void testLoginWithFacebookWebFlow() throws java.lang.Throwable;
|
41
|
+
public void testLoginWithWrongCredentials();
|
42
|
+
public void testNoGooglePlusAccountLogin();
|
43
|
+
public void testRecoverPassword() throws java.lang.Throwable;
|
44
|
+
public void testRecoverPasswordNoInput();
|
45
|
+
public void testSCUserLoginFlow();
|
46
|
+
}
|
47
|
+
JAVAP
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rubotium::Adb::Devices do
|
4
|
+
let(:devices) { described_class.new }
|
5
|
+
|
6
|
+
it 'should return list of devices' do
|
7
|
+
Rubotium::CMD.stub(:run_command).and_return(Fixtures::Adb::Devices.two_devices_attached)
|
8
|
+
devices.list.should == ['emulator-5554', 'emulator-5556']
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should not return offline devices' do
|
12
|
+
Rubotium::CMD.stub(:run_command).and_return(Fixtures::Adb::Devices.two_devices_attached_one_is_offline)
|
13
|
+
devices.list.should == ['emulator-5556']
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should return one device' do
|
17
|
+
Rubotium::CMD.stub(:run_command).and_return(Fixtures::Adb::Devices.one_device)
|
18
|
+
devices.list.should == ['emulator-5554']
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should return zero devices if none are attached' do
|
22
|
+
Rubotium::CMD.stub(:run_command).and_return(Fixtures::Adb::Devices.one_device_offline)
|
23
|
+
devices.list.should == []
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rubotium::Adb::Instrumentation do
|
4
|
+
let (:instr) { described_class }
|
5
|
+
let(:runable_test) {double(RunableTest)}
|
6
|
+
|
7
|
+
context 'running tests' do
|
8
|
+
let (:inst) { instr.new(" ") }
|
9
|
+
it 'should raise error if test runner name is not set' do
|
10
|
+
inst.test_package_name = "test_package"
|
11
|
+
expect { inst.run_test(runable_test) }.to raise_error (Rubotium::Adb::NoTestRunnerError)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should raise error if test package name is not set' do
|
15
|
+
inst.test_runner = "runner"
|
16
|
+
expect { inst.run_test(runable_test) }.to raise_error (Rubotium::Adb::NoTestPackageError)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'runs correct test' do
|
20
|
+
runable_test.stub(:package_name).and_return("package")
|
21
|
+
runable_test.stub(:test_name).and_return("test")
|
22
|
+
inst.test_package_name = "package_name"
|
23
|
+
inst.test_runner = "TestRunner"
|
24
|
+
|
25
|
+
command = "am instrument -w -e class package#test package_name/TestRunner"
|
26
|
+
Rubotium::Adb::Shell.any_instance.should_receive(:run_command).with(command)
|
27
|
+
Rubotium::Adb::Shell.any_instance.stub(:run_command).and_return(Fixtures::Adb.test_success)
|
28
|
+
inst.run_test(runable_test)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rubotium::Adb::TestResultParser do
|
4
|
+
let(:parser) { described_class }
|
5
|
+
|
6
|
+
context 'failed test' do
|
7
|
+
let(:parsed_result) { parser.new(Fixtures::Adb.test_failure, "", "") }
|
8
|
+
|
9
|
+
it 'should not be passed' do
|
10
|
+
parsed_result.should_not be_passed
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be failed' do
|
14
|
+
parsed_result.should be_failed
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should not be errored' do
|
18
|
+
parsed_result.should_not be_errored
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should get the stack trace' do
|
22
|
+
parsed_result.stack_trace.should == Fixtures::Adb.test_failure_stack_trace
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should get test's duration time" do
|
26
|
+
parsed_result.time.should be_eql 6.485
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should not have error message' do
|
30
|
+
parsed_result.error_message.should be_empty
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'passed test' do
|
35
|
+
let(:parsed_result) { parser.new(Fixtures::Adb.test_success, "", "") }
|
36
|
+
|
37
|
+
it 'should be passed' do
|
38
|
+
parsed_result.should be_passed
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should not be failed' do
|
42
|
+
parsed_result.should_not be_failed
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should not be errored' do
|
46
|
+
parsed_result.should_not be_errored
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should not have a stack trace' do
|
50
|
+
parsed_result.stack_trace.should be_empty
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should get test's duration" do
|
54
|
+
parsed_result.time.should be_eql 5.873
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should not have error message' do
|
58
|
+
parsed_result.error_message.should be_empty
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'error in test' do
|
63
|
+
let(:parsed_result) { parser.new(Fixtures::Adb.test_error, "", "") }
|
64
|
+
|
65
|
+
it 'should not be passed' do
|
66
|
+
parsed_result.should_not be_passed
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should be failed' do
|
70
|
+
parsed_result.should be_failed
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should not be errored' do
|
74
|
+
parsed_result.should_not be_errored
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should get the stack trace' do
|
78
|
+
parsed_result.stack_trace.should == Fixtures::Adb.test_error_stack_trace
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should get test's duration time" do
|
82
|
+
parsed_result.time.should be_eql 4.314
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should not have error message' do
|
86
|
+
parsed_result.error_message.should be_empty
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'run error' do
|
91
|
+
let(:parsed_result) { parser.new(Fixtures::Adb.test_run_error, "", "") }
|
92
|
+
|
93
|
+
it 'should not be passed' do
|
94
|
+
parsed_result.should_not be_passed
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should not be failed' do
|
98
|
+
parsed_result.should_not be_failed
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should be errored' do
|
102
|
+
parsed_result.should be_errored
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should not take time to execute' do
|
106
|
+
parsed_result.time.should be_eql 0
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should know the error reason' do
|
110
|
+
parsed_result.error_message.should be_eql Fixtures::Adb.error_message
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should not have a stack trace' do
|
114
|
+
parsed_result.stack_trace.should be_empty
|
115
|
+
end
|
116
|
+
end
|
117
|
+
context 'passed tests with negative time' do
|
118
|
+
let(:parsed_result) { parser.new(Fixtures::Adb.passed_negative_time, "", "") }
|
119
|
+
|
120
|
+
it 'should not be passed' do
|
121
|
+
parsed_result.time.should == 53.656
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'system crash' do
|
126
|
+
let(:parsed_result) { parser.new(Fixtures::Adb.system_crash, "", "") }
|
127
|
+
|
128
|
+
it 'should know the error reason' do
|
129
|
+
parsed_result.error_message.should == "System has crashed.\r"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rubotium::Adb::Shell do
|
4
|
+
let(:shell) { described_class }
|
5
|
+
before { Rubotium::CMD.stub(:run_command) }
|
6
|
+
|
7
|
+
context 'with no device given' do
|
8
|
+
it 'should execute commands without device' do
|
9
|
+
shell.new(nil).send(:command).should == "adb shell"
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should execute commands if device string is empty' do
|
13
|
+
shell.new("").send(:command).should == "adb shell"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with given device' do
|
18
|
+
it 'should execute commands on a device' do
|
19
|
+
shell.new("12345").send(:command).should == "adb -s 12345 shell"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rubotium::Devices do
|
4
|
+
let(:devices_class) {described_class}
|
5
|
+
|
6
|
+
before do
|
7
|
+
Rubotium::Device.stub(:new).and_return("Device_Instance")
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'given device' do
|
11
|
+
let(:devices) {devices_class.new('emulator')}
|
12
|
+
|
13
|
+
it 'should complain about device being not accessible' do
|
14
|
+
Rubotium::Adb::Devices.any_instance.stub(:list).and_return([])
|
15
|
+
expect { devices.all }.to raise_error(Rubotium::NoDevicesError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should complain about not matched devices' do
|
19
|
+
Rubotium::Adb::Devices.any_instance.stub(:list).and_return(['nexus'])
|
20
|
+
expect { devices.all }.to raise_error(Rubotium::NoMatchedDevicesError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should return test runner per device' do
|
24
|
+
Rubotium::Adb::Devices.any_instance.stub(:list).and_return(['emulator'])
|
25
|
+
devices.all.should == [ "Device_Instance" ]
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should match devices' do
|
29
|
+
Rubotium::Adb::Devices.any_instance.stub(:list).and_return(['emulator', 'amolator', 'nexus', 'emulatores111', '113242'])
|
30
|
+
devices.send(:matched_devices, 'emulator').should == ["emulator", "emulatores111"]
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'without device' do
|
36
|
+
let(:devices) { devices_class.new }
|
37
|
+
|
38
|
+
it 'should use all available devices' do
|
39
|
+
Rubotium::Adb::Devices.any_instance.stub(:list).and_return(['emulator', 'amolator', 'nexus', 'emulatores111', '113242'])
|
40
|
+
devices.all.should == ["Device_Instance", "Device_Instance", "Device_Instance", "Device_Instance", "Device_Instance"]
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|