rubotium 0.0.4 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/bin/rubotium +4 -2
  4. data/lib/rubotium/adb/commands/command.rb +55 -0
  5. data/lib/rubotium/adb/commands/install_command.rb +19 -0
  6. data/lib/rubotium/adb/commands/instrument_command.rb +27 -0
  7. data/lib/rubotium/adb/commands/memory_command.rb +19 -0
  8. data/lib/rubotium/adb/commands/pull_command.rb +19 -0
  9. data/lib/rubotium/adb/commands/shell_command.rb +21 -0
  10. data/lib/rubotium/adb/commands/uninstall_command.rb +19 -0
  11. data/lib/rubotium/adb/commands.rb +7 -0
  12. data/lib/rubotium/adb/devices.rb +15 -6
  13. data/lib/rubotium/adb/parsers/procrank.rb +51 -0
  14. data/lib/rubotium/adb/parsers/single_test_result_parser.rb +61 -0
  15. data/lib/rubotium/adb/parsers/test_results_parser.rb +69 -0
  16. data/lib/rubotium/adb/parsers.rb +3 -0
  17. data/lib/rubotium/adb/test_result_parser.rb +5 -4
  18. data/lib/rubotium/adb.rb +3 -5
  19. data/lib/rubotium/apk/android_apk.rb +102 -0
  20. data/lib/rubotium/apk.rb +2 -2
  21. data/lib/rubotium/cmd.rb +1 -1
  22. data/lib/rubotium/device.rb +19 -33
  23. data/lib/rubotium/devices.rb +27 -14
  24. data/lib/rubotium/formatters/junit_formatter.rb +10 -11
  25. data/lib/rubotium/memory/data_point.rb +63 -0
  26. data/lib/rubotium/memory/monitor.rb +65 -0
  27. data/lib/rubotium/memory.rb +8 -0
  28. data/lib/rubotium/package.rb +7 -4
  29. data/lib/rubotium/runnable_test.rb +13 -0
  30. data/lib/rubotium/test_cases_reader.rb +32 -0
  31. data/lib/rubotium/test_result.rb +52 -0
  32. data/lib/rubotium/test_results.rb +18 -0
  33. data/lib/rubotium/test_runners/instrumentation_test_runner.rb +24 -0
  34. data/lib/rubotium/tests_runner.rb +80 -0
  35. data/lib/rubotium/version.rb +1 -1
  36. data/lib/rubotium.rb +54 -41
  37. data/rubotium.gemspec +0 -1
  38. data/spec/fixtures/adb_raw_result.rb +138 -0
  39. data/spec/fixtures/adb_raw_results.rb +153 -0
  40. data/spec/fixtures/adb_results.rb +4 -0
  41. data/spec/lib/rubotium/adb/adb_devices_spec.rb +43 -12
  42. data/spec/lib/rubotium/adb/adb_result_parser_spec.rb +22 -7
  43. data/spec/lib/rubotium/adb/adb_shell_spec.rb +11 -6
  44. data/spec/lib/rubotium/adb/parsers/procrank_spec.rb +61 -0
  45. data/spec/lib/rubotium/adb/parsers/single_test_result_parser_spec.rb +116 -0
  46. data/spec/lib/rubotium/adb/parsers/test_results_parser_spec.rb +108 -0
  47. data/spec/lib/rubotium/apk/android_apk_spec.rb +37 -0
  48. data/spec/lib/rubotium/apk/mock/BarcodeScanner4.2.apk +0 -0
  49. data/spec/lib/rubotium/apk/mock/UECExpress.apk +0 -0
  50. data/spec/lib/rubotium/apk/mock/dummy.apk +1 -0
  51. data/spec/lib/rubotium/apk/mock/sample.apk +0 -0
  52. data/spec/lib/rubotium/device_spec.rb +38 -0
  53. data/spec/lib/rubotium/devices_spec.rb +41 -24
  54. data/spec/lib/rubotium/memory/data_point_spec.rb +42 -0
  55. data/spec/lib/rubotium/memory/monitor_spec.rb +6 -0
  56. data/spec/lib/rubotium/tests_runner_spec.rb +47 -0
  57. data/spec/spec_helper.rb +2 -0
  58. data/test.rb +11 -0
  59. metadata +62 -41
  60. data/lib/rubotium/adb/command.rb +0 -21
  61. data/lib/rubotium/adb/install_command.rb +0 -17
  62. data/lib/rubotium/adb/instrumentation.rb +0 -36
  63. data/lib/rubotium/adb/uninstall_command.rb +0 -17
  64. data/lib/rubotium/apk/converter.rb +0 -22
  65. data/lib/rubotium/grouper.rb +0 -40
  66. data/lib/rubotium/jar_reader.rb +0 -70
  67. data/lib/rubotium/runable_test.rb +0 -11
  68. data/lib/rubotium/test_case.rb +0 -6
  69. data/lib/rubotium/test_suite.rb +0 -12
  70. data/spec/lib/rubotium/adb/adb_instrumentation_spec.rb +0 -32
  71. data/spec/lib/rubotium/grouper_spec.rb +0 -56
  72. data/spec/lib/rubotium/jar_reader_spec.rb +0 -58
data/lib/rubotium.rb CHANGED
@@ -1,16 +1,23 @@
1
1
  require 'rubotium/version'
2
- require 'rubotium/jar_reader'
3
2
  require 'rubotium/adb'
4
3
  require 'rubotium/apk'
5
4
  require 'rubotium/cmd'
6
5
  require 'rubotium/device'
7
6
  require 'rubotium/devices'
7
+ require 'rubotium/tests_runner'
8
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'
9
+ require 'rubotium/runnable_test'
13
10
  require 'rubotium/package'
11
+ require 'rubotium/memory'
12
+ require 'rubotium/adb/parsers/procrank'
13
+ require 'rubotium/test_runners/instrumentation_test_runner'
14
+ require 'rubotium/test_results'
15
+ require 'rubotium/test_cases_reader'
16
+ require 'rubotium/test_result'
17
+
18
+ require 'fileutils'
19
+ require 'json'
20
+ require 'logger'
14
21
 
15
22
  require 'parallel'
16
23
  module Rubotium
@@ -22,58 +29,64 @@ module Rubotium
22
29
 
23
30
  class NoTestSuiteError < Error; end
24
31
 
32
+ class NoAaptError < Error; end
33
+
34
+ class NoJavapError < Error; end
35
+
25
36
  class << self
26
37
  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
38
+ raise RuntimeError, "Empty configuration" if opts.empty?
39
+ raise Errno::ENOENT, "Tests apk does not exist" if !File.exist?(opts[:tests_apk_path])
40
+ raise Errno::ENOENT, "App apk does not exist" if !File.exist?(opts[:app_apk_path])
46
41
 
47
- tests_count = 0
48
- test_suites.each{|test_suite|
49
- tests_count = tests_count + test_suite.test_cases.count
50
- }
42
+ logger.level = Logger::INFO
51
43
 
52
- puts "There are #{test_suites.count} packages with tests in the Jar file"
53
- puts "#{tests_count} tests to run"
44
+ startTime = Time.now
45
+ FileUtils.mkdir_p('results')
46
+ FileUtils.mkdir_p('results/memory_logs')
47
+ FileUtils.mkdir_p('screens')
48
+ FileUtils.mkdir_p('logs')
54
49
 
55
- devices = Devices.new(opts[:device_matcher]).all
56
- test_suites = Grouper.new(test_suites, devices.count).create_groups
50
+ application_package = Rubotium::Package.new(opts[:app_apk_path])
51
+ tests_package = Rubotium::Package.new(opts[:tests_apk_path], opts[:runner])
57
52
 
58
- devices.each_with_index{|device, index|
59
- device.test_package_name = tests_package.name
60
- device.test_runner_name = test_runner || "android.test.InstrumentationTestRunner"
61
- device.testsuite = test_suites[index]
62
- }
53
+ devices = Devices.new(:name => opts[:device_matcher]).all
63
54
 
64
- devices = Parallel.map(devices, :in_processes=> devices.count) {|device|
55
+ devices = Parallel.map(devices, :in_threads => devices.count) {|device|
65
56
  device.uninstall application_package.name
66
57
  device.install application_package.path
67
58
  device.uninstall tests_package.name
68
59
  device.install tests_package.path
69
- device.run_tests
70
60
  device
71
61
  }
72
62
 
73
- puts "Tests took: #{Time.at(Time.now-startTime).utc.strftime("%H:%M:%S")}"
63
+ test_suites = Rubotium::TestCasesReader.new(devices.first, tests_package).read_tests
64
+ puts "There are #{test_suites.count} tests to run"
65
+
66
+ runner = Rubotium::TestsRunner.new(devices, test_suites, tests_package, {:annotation=>opts[:annotation]})
67
+ runner.run_tests
68
+
69
+ FileUtils.mkdir_p(['screens', 'logs'])
70
+
74
71
  devices.each{|device|
75
- Formatters::JunitFormatter.new(device, opts[:report])
72
+ device.pull('/sdcard/Robotium-Screenshots')
73
+ device.pull('/sdcard/RobotiumLogs')
74
+ device.shell('rm -R /sdcard/Robotium-Screenshots ')
75
+ device.shell('rm -R /sdcard/RobotiumLogs ')
76
76
  }
77
+ FileUtils.mv(Dir.glob('*.jpg'), 'screens')
78
+ FileUtils.mv(Dir.glob('*.log'), 'logs')
79
+
80
+ puts "Tests took: #{Time.at(Time.now-startTime).utc.strftime("%H:%M:%S")}"
81
+
82
+ Formatters::JunitFormatter.new(runner.tests_results.group_by_package, opts[:report])
83
+
84
+ end
85
+
86
+ def logger
87
+ @@logger ||= Logger.new(STDOUT).tap do |log|
88
+ log.progname = 'name-of-subsystem'
89
+ end
77
90
  end
78
91
  end
79
92
  end
data/rubotium.gemspec CHANGED
@@ -29,5 +29,4 @@ Gem::Specification.new do |spec|
29
29
  spec.add_dependency 'trollop', '2.0'
30
30
  spec.add_dependency 'parallel', '0.9.2'
31
31
  spec.add_dependency 'dex2jar', '0.0.6'
32
- spec.add_dependency 'android_apk', '0.7.0'
33
32
  end
@@ -0,0 +1,138 @@
1
+ module Fixtures
2
+ class AdbRawResult
3
+ class << self
4
+ def successful_test_result
5
+ "INSTRUMENTATION_STATUS_CODE: 1
6
+ INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
7
+ INSTRUMENTATION_STATUS: current=1
8
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.MenuCrashTest
9
+ INSTRUMENTATION_STATUS: stream=.
10
+ INSTRUMENTATION_STATUS: numtests=150
11
+ INSTRUMENTATION_STATUS: test=testMenuCrash
12
+ INSTRUMENTATION_STATUS_CODE: 0"
13
+ end
14
+
15
+ def single_failed_test_result
16
+ "INSTRUMENTATION_STATUS_CODE: 9
17
+ INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
18
+ INSTRUMENTATION_STATUS: current=1
19
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.MenuCrashTest
20
+ INSTRUMENTATION_STATUS: stream=
21
+ Failure in testMenuCrash:
22
+ junit.framework.AssertionFailedError
23
+ at com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:22)
24
+ at java.lang.reflect.Method.invokeNative(Native Method)
25
+ at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
26
+ at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
27
+ at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
28
+ at com.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:100)
29
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
30
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
31
+ at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
32
+ at com.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)
33
+ at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
34
+
35
+ INSTRUMENTATION_STATUS: numtests=1
36
+ INSTRUMENTATION_STATUS: stack=junit.framework.AssertionFailedError
37
+ at com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:22)
38
+ at java.lang.reflect.Method.invokeNative(Native Method)
39
+ at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
40
+ at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
41
+ at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
42
+ at com.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:100)
43
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
44
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
45
+ at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
46
+ at com.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)
47
+ at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
48
+
49
+ INSTRUMENTATION_STATUS: test=testMenuCrash
50
+ INSTRUMENTATION_STATUS_CODE: -2"
51
+ end
52
+
53
+ def single_failed_test_stack_trace
54
+ "junit.framework.AssertionFailedError
55
+ at com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:22)
56
+ at java.lang.reflect.Method.invokeNative(Native Method)
57
+ at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
58
+ at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
59
+ at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
60
+ at com.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:100)
61
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
62
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
63
+ at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
64
+ at com.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)
65
+ at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)"
66
+ end
67
+
68
+ def single_errored_test_result
69
+ "INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
70
+ INSTRUMENTATION_STATUS: current=1
71
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.MenuCrashTest
72
+ INSTRUMENTATION_STATUS: stream=
73
+ com.soundcloud.android.MenuCrashTest:
74
+ INSTRUMENTATION_STATUS: numtests=1
75
+ INSTRUMENTATION_STATUS: test=testMenuCrash
76
+ INSTRUMENTATION_STATUS_CODE: 1
77
+ INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
78
+ INSTRUMENTATION_STATUS: current=1
79
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.MenuCrashTest
80
+ INSTRUMENTATION_STATUS: stream=
81
+ Error in testMenuCrash:
82
+ java.lang.NullPointerException
83
+ at com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:21)
84
+ at java.lang.reflect.Method.invokeNative(Native Method)
85
+ at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
86
+ at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
87
+ at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
88
+ at com.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:102)
89
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
90
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
91
+ at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
92
+ at com.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)
93
+ at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
94
+
95
+ INSTRUMENTATION_STATUS: numtests=1
96
+ INSTRUMENTATION_STATUS: stack=java.lang.NullPointerException
97
+ at com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:21)
98
+ at java.lang.reflect.Method.invokeNative(Native Method)
99
+ at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
100
+ at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
101
+ at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
102
+ at com.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:102)
103
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
104
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
105
+ at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
106
+ at com.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)
107
+ at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
108
+
109
+ INSTRUMENTATION_STATUS: test=testMenuCrash
110
+ INSTRUMENTATION_STATUS_CODE: -1"
111
+ end
112
+
113
+ def single_errored_test_result_stack_trace
114
+ "java.lang.NullPointerException
115
+ at com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:21)
116
+ at java.lang.reflect.Method.invokeNative(Native Method)
117
+ at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
118
+ at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
119
+ at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
120
+ at com.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:102)
121
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
122
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
123
+ at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
124
+ at com.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)
125
+ at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)"
126
+ end
127
+
128
+ def such_error_wow
129
+ "INSTRUMENTATION_STATUS_CODE: 1\r\nINSTRUMENTATION_STATUS: numtests=1\r\nINSTRUMENTATION_STATUS: stream=\r\nError in testMenuCrash:\r\njava.lang.NullPointerException\r\n\tat com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:21)\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.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:102)\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.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)\r\n\tat android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)\r\n\r\nINSTRUMENTATION_STATUS: id=InstrumentationTestRunner\r\nINSTRUMENTATION_STATUS: test=testMenuCrash\r\nINSTRUMENTATION_STATUS: class=com.soundcloud.android.MenuCrashTest\r\nINSTRUMENTATION_STATUS: stack=java.lang.NullPointerException\r\n\tat com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:21)\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.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:102)\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.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)\r\n\tat android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)\r\n\r\nINSTRUMENTATION_STATUS: current=1\r\nINSTRUMENTATION_STATUS_CODE: -1"
130
+ end
131
+
132
+ def such_error_stack_trace
133
+ "java.lang.NullPointerException\r\n\tat com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:21)\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.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:102)\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.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)\r\n\tat android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)"
134
+ end
135
+ end
136
+ end
137
+ end
138
+
@@ -0,0 +1,153 @@
1
+ module Fixtures
2
+ class AdbRawResults
3
+ class << self
4
+ def multiple_test_results
5
+ "INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
6
+ INSTRUMENTATION_STATUS: current=1
7
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.MenuCrashTest
8
+ INSTRUMENTATION_STATUS: stream=
9
+ com.soundcloud.android.MenuCrashTest:
10
+ INSTRUMENTATION_STATUS: numtests=150
11
+ INSTRUMENTATION_STATUS: test=testMenuCrash
12
+ INSTRUMENTATION_STATUS_CODE: 1
13
+ INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
14
+ INSTRUMENTATION_STATUS: current=1
15
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.MenuCrashTest
16
+ INSTRUMENTATION_STATUS: stream=.
17
+ INSTRUMENTATION_STATUS: numtests=150
18
+ INSTRUMENTATION_STATUS: test=testMenuCrash
19
+ INSTRUMENTATION_STATUS_CODE: 0
20
+ INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
21
+ INSTRUMENTATION_STATUS: current=2
22
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.StreamTest
23
+ INSTRUMENTATION_STATUS: stream=
24
+ com.soundcloud.android.StreamTest:
25
+ INSTRUMENTATION_STATUS: numtests=150
26
+ INSTRUMENTATION_STATUS: test=testStreamContainsItems
27
+ INSTRUMENTATION_STATUS_CODE: 1
28
+ INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
29
+ INSTRUMENTATION_STATUS: current=2
30
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.StreamTest
31
+ INSTRUMENTATION_STATUS: stream=.
32
+ INSTRUMENTATION_STATUS: numtests=150
33
+ INSTRUMENTATION_STATUS: test=testStreamContainsItems
34
+ INSTRUMENTATION_STATUS_CODE: -1
35
+ INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
36
+ INSTRUMENTATION_STATUS: current=3
37
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.StreamTest
38
+ INSTRUMENTATION_STATUS: stream=
39
+ INSTRUMENTATION_STATUS: numtests=150
40
+ INSTRUMENTATION_STATUS: test=testStreamShouldHaveCorrectTitle
41
+ INSTRUMENTATION_STATUS_CODE: 1
42
+ INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
43
+ INSTRUMENTATION_STATUS: current=3
44
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.StreamTest
45
+ INSTRUMENTATION_STATUS: stream=.
46
+ INSTRUMENTATION_STATUS: numtests=150
47
+ INSTRUMENTATION_STATUS: test=testStreamShouldHaveCorrectTitle
48
+ INSTRUMENTATION_STATUS_CODE: -2
49
+ INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
50
+ INSTRUMENTATION_STATUS: current=4
51
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.activities.Activities
52
+ INSTRUMENTATION_STATUS: stream=
53
+ com.soundcloud.android.activities.Activities:
54
+ INSTRUMENTATION_STATUS: numtests=150
55
+ INSTRUMENTATION_STATUS: test=testCommentGoesToCommentsScreen
56
+ INSTRUMENTATION_RESULT: stream=
57
+ Test results for RandomizingRunner=.........................................
58
+ .........................................
59
+ .........................................
60
+ ...........................
61
+ Time: 0.142
62
+
63
+ OK (150 tests)"
64
+ end
65
+
66
+ def test_cannot_start_error
67
+ "INSTRUMENTATION_STATUS: id=ActivityManagerService
68
+ INSTRUMENTATION_STATUS: Error=Unable to find instrumentation info for: ComponentInfo{com.soundcloud.android.tests/com.soundcloud.android.tests.RandomizingRunnr}
69
+ INSTRUMENTATION_STATUS_CODE: -1
70
+ android.util.AndroidException: INSTRUMENTATION_FAILED: com.soundcloud.android.tests/com.soundcloud.android.tests.RandomizingRunnr
71
+ at com.android.commands.am.Am.runInstrument(Am.java:802)
72
+ at com.android.commands.am.Am.onRun(Am.java:242)
73
+ at com.android.internal.os.BaseCommand.run(BaseCommand.java:47)
74
+ at com.android.commands.am.Am.main(Am.java:75)
75
+ at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
76
+ at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:235)
77
+ at dalvik.system.NativeStart.main(Native Method)"
78
+ end
79
+
80
+ def test_run_error
81
+ "INSTRUMENTATION_RESULT: shortMsg=java.lang.RuntimeException
82
+ INSTRUMENTATION_RESULT: longMsg=java.lang.RuntimeException: Could not find test class. Class: com.soundcloud.android.MenuCrashTests
83
+ INSTRUMENTATION_CODE: 0"
84
+ end
85
+
86
+ def app_crashed_during_tests
87
+ "INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
88
+ INSTRUMENTATION_STATUS: current=1
89
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.MenuCrashTest
90
+ INSTRUMENTATION_STATUS: stream=
91
+ com.soundcloud.android.MenuCrashTest:
92
+ INSTRUMENTATION_STATUS: numtests=1
93
+ INSTRUMENTATION_STATUS: test=testMenuCrash
94
+ INSTRUMENTATION_STATUS_CODE: 1
95
+ INSTRUMENTATION_RESULT: shortMsg=java.lang.RuntimeException
96
+ INSTRUMENTATION_RESULT: longMsg=java.lang.RuntimeException: developer requested crash
97
+ INSTRUMENTATION_CODE: 0"
98
+ end
99
+
100
+ def single_failed_test
101
+ "INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
102
+ INSTRUMENTATION_STATUS: current=1
103
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.MenuCrashTest
104
+ INSTRUMENTATION_STATUS: stream=
105
+ com.soundcloud.android.MenuCrashTest:
106
+ INSTRUMENTATION_STATUS: numtests=1
107
+ INSTRUMENTATION_STATUS: test=testMenuCrash
108
+ INSTRUMENTATION_STATUS_CODE: 1
109
+ INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
110
+ INSTRUMENTATION_STATUS: current=1
111
+ INSTRUMENTATION_STATUS: class=com.soundcloud.android.MenuCrashTest
112
+ INSTRUMENTATION_STATUS: stream=
113
+ Failure in testMenuCrash:
114
+ junit.framework.AssertionFailedError
115
+ at com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:22)
116
+ at java.lang.reflect.Method.invokeNative(Native Method)
117
+ at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
118
+ at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
119
+ at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
120
+ at com.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:100)
121
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
122
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
123
+ at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
124
+ at com.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)
125
+ at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
126
+
127
+ INSTRUMENTATION_STATUS: numtests=1
128
+ INSTRUMENTATION_STATUS: stack=junit.framework.AssertionFailedError
129
+ at com.soundcloud.android.MenuCrashTest.testMenuCrash(MenuCrashTest.java:22)
130
+ at java.lang.reflect.Method.invokeNative(Native Method)
131
+ at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
132
+ at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
133
+ at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
134
+ at com.soundcloud.android.tests.ActivityTestCase.runTest(ActivityTestCase.java:100)
135
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
136
+ at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
137
+ at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
138
+ at com.soundcloud.android.tests.RandomizingRunner.onStart(RandomizingRunner.java:11)
139
+ at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
140
+
141
+ INSTRUMENTATION_STATUS: test=testMenuCrash
142
+ INSTRUMENTATION_STATUS_CODE: -2
143
+ INSTRUMENTATION_RESULT: stream=
144
+ Test results for RandomizingRunner=.F
145
+ Time: 16.79
146
+
147
+ FAILURES!!!
148
+ Tests run: 1, Failures: 1, Errors: 0"
149
+ end
150
+ end
151
+ end
152
+ end
153
+
@@ -55,6 +55,10 @@ module Fixtures
55
55
  def system_crash
56
56
  "\r\ncom.android.player.Player:INSTRUMENTATION_ABORTED: System has crashed.\r\n"
57
57
  end
58
+
59
+ def gingerbread_exception
60
+ "android.util.AndroidException: INSTRUMENTATION_FAILED: com.soundcloud.android.tests/android.test.InstrumentationTestRunner\r\n"
61
+ end
58
62
  end
59
63
  end
60
64
  end
@@ -3,23 +3,54 @@ require 'spec_helper'
3
3
  describe Rubotium::Adb::Devices do
4
4
  let(:devices) { described_class.new }
5
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']
6
+ before do
7
+ devices.stub(:create_device) {|serial|
8
+ OpenStruct.new(:name => serial)
9
+ }
9
10
  end
10
11
 
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']
12
+ context 'with one device attached' do
13
+ before do
14
+ Rubotium::CMD.stub(:run_command).and_return(Fixtures::Adb::Devices.one_device)
15
+ end
16
+
17
+ it 'should return one device' do
18
+ devices.attached.count == 1
19
+ end
14
20
  end
15
21
 
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']
22
+ context 'when two devices are attached' do
23
+ before do
24
+ Rubotium::CMD.stub(:run_command).and_return(Fixtures::Adb::Devices.two_devices_attached)
25
+ end
26
+ it 'should return list of devices' do
27
+ devices.attached.count.should == 2
28
+ end
29
+
30
+ it 'should return two different devices' do
31
+ devices.attached.first.should_not eql(devices.attached.last)
32
+ end
33
+ end
34
+
35
+ context 'with offline devices' do
36
+ before do
37
+ Rubotium::CMD.stub(:run_command).and_return(Fixtures::Adb::Devices.two_devices_attached_one_is_offline)
38
+ end
39
+ it 'should not return offline devices' do
40
+ devices.attached.count.should == 1
41
+ end
42
+
43
+ it 'should return attached device' do
44
+ devices.attached.first.name.should eql('emulator-5556')
45
+ end
19
46
  end
20
47
 
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 == []
48
+ context 'with no devices attached' do
49
+ before do
50
+ Rubotium::CMD.stub(:run_command).and_return(Fixtures::Adb::Devices.one_device_offline)
51
+ end
52
+ it 'should return zero devices if none are attached' do
53
+ devices.attached.should == []
54
+ end
24
55
  end
25
56
  end
@@ -2,9 +2,10 @@ require 'spec_helper'
2
2
 
3
3
  describe Rubotium::Adb::TestResultParser do
4
4
  let(:parser) { described_class }
5
+ let(:package) { double(Rubotium::Package, :package_name=> 'name', :test_name=> 'test_name')}
5
6
 
6
7
  context 'failed test' do
7
- let(:parsed_result) { parser.new(Fixtures::Adb.test_failure, "", "") }
8
+ let(:parsed_result) { parser.new(Fixtures::Adb.test_failure, package, "") }
8
9
 
9
10
  it 'should not be passed' do
10
11
  parsed_result.should_not be_passed
@@ -32,7 +33,7 @@ describe Rubotium::Adb::TestResultParser do
32
33
  end
33
34
 
34
35
  context 'passed test' do
35
- let(:parsed_result) { parser.new(Fixtures::Adb.test_success, "", "") }
36
+ let(:parsed_result) { parser.new(Fixtures::Adb.test_success, package, "") }
36
37
 
37
38
  it 'should be passed' do
38
39
  parsed_result.should be_passed
@@ -60,7 +61,7 @@ describe Rubotium::Adb::TestResultParser do
60
61
  end
61
62
 
62
63
  context 'error in test' do
63
- let(:parsed_result) { parser.new(Fixtures::Adb.test_error, "", "") }
64
+ let(:parsed_result) { parser.new(Fixtures::Adb.test_error, package, "") }
64
65
 
65
66
  it 'should not be passed' do
66
67
  parsed_result.should_not be_passed
@@ -88,7 +89,7 @@ describe Rubotium::Adb::TestResultParser do
88
89
  end
89
90
 
90
91
  context 'run error' do
91
- let(:parsed_result) { parser.new(Fixtures::Adb.test_run_error, "", "") }
92
+ let(:parsed_result) { parser.new(Fixtures::Adb.test_run_error, package, "") }
92
93
 
93
94
  it 'should not be passed' do
94
95
  parsed_result.should_not be_passed
@@ -115,7 +116,7 @@ describe Rubotium::Adb::TestResultParser do
115
116
  end
116
117
  end
117
118
  context 'passed tests with negative time' do
118
- let(:parsed_result) { parser.new(Fixtures::Adb.passed_negative_time, "", "") }
119
+ let(:parsed_result) { parser.new(Fixtures::Adb.passed_negative_time, package, "") }
119
120
 
120
121
  it 'should not be passed' do
121
122
  parsed_result.time.should == 53.656
@@ -123,10 +124,24 @@ describe Rubotium::Adb::TestResultParser do
123
124
  end
124
125
 
125
126
  context 'system crash' do
126
- let(:parsed_result) { parser.new(Fixtures::Adb.system_crash, "", "") }
127
+ let(:parsed_result) { parser.new(Fixtures::Adb.system_crash, package, "") }
127
128
 
128
129
  it 'should know the error reason' do
129
130
  parsed_result.error_message.should == "System has crashed.\r"
130
131
  end
131
132
  end
132
- end
133
+
134
+ context 'command_timeout' do
135
+ let(:parsed_result) { parser.new(Fixtures::Adb.gingerbread_exception, package, "") }
136
+
137
+ it 'should behave as error case' do
138
+ pending
139
+ parsed_result.should be_errored
140
+ end
141
+
142
+ it 'should know the error reason' do
143
+ pending
144
+ parsed_result.error_message.should eql('')
145
+ end
146
+ end
147
+ end
@@ -1,22 +1,27 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Rubotium::Adb::Shell do
4
- let(:shell) { described_class }
5
- before { Rubotium::CMD.stub(:run_command) }
6
-
7
4
  context 'with no device given' do
5
+ let(:shell) { described_class.new('') }
6
+
8
7
  it 'should execute commands without device' do
9
- shell.new(nil).send(:command).should == "adb shell"
8
+ shell.send(:command).should == "adb shell"
10
9
  end
11
10
 
12
11
  it 'should execute commands if device string is empty' do
13
- shell.new("").send(:command).should == "adb shell"
12
+ shell.send(:command).should == "adb shell"
14
13
  end
15
14
  end
16
15
 
17
16
  context 'with given device' do
17
+ let(:shell) { described_class.new('12345') }
18
18
  it 'should execute commands on a device' do
19
- shell.new("12345").send(:command).should == "adb -s 12345 shell"
19
+ shell.send(:command).should == "adb -s 12345 shell"
20
+ end
21
+
22
+ it 'should execute commands' do
23
+ expect(Rubotium::CMD).to receive(:run_command).with('adb -s 12345 shell foo')
24
+ shell.run_command('foo')
20
25
  end
21
26
  end
22
27