rubotium 0.0.4 → 0.0.7

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.
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