1. introduction to android
testing
a hands-on approach
Copyright (C) 2011 Diego Torres Milano All rights reserved
2. diego torres milano
android system engineer
flextronics
http://dtmilano.blogspot.com
Copyright (C) 2011 Diego Torres Milano All rights reserved
3. “Never test the depth of
the water with both feet.”
-- Anonymous
Copyright (C) 2011 Diego Torres Milano All rights reserved
4. agenda
android testing background
test driven development
code coverage
continuous integration
behavior driven development
Copyright (C) 2011 Diego Torres Milano All rights reserved
5. operating systems
July 2011
Android
150M
iOS
222M
Copyright (C) 2011 Diego Torres Milano All rights reserved
6. android testing
background
Copyright (C) 2011 Diego Torres Milano All rights reserved
8. Why
?
Copyright (C) 2011 Diego Torres Milano All rights reserved
9. What Why
?
Copyright (C) 2011 Diego Torres Milano All rights reserved
10. What Why
When ?
Copyright (C) 2011 Diego Torres Milano All rights reserved
11. What Why
When
how
?
Copyright (C) 2011 Diego Torres Milano All rights reserved
12. types of test
tests
unit
functional
performance
integration
Copyright (C) 2011 Diego Torres Milano All rights reserved
13. types of test
unit
Copyright (C) 2011 Diego Torres Milano All rights reserved
14. types of test
by programmers for programmers
unit
Copyright (C) 2011 Diego Torres Milano All rights reserved
15. types of test
by programmers for programmers
unit
in a programming language
Copyright (C) 2011 Diego Torres Milano All rights reserved
16. types of test
by programmers for programmers
unit
in a programming language
JUnit is the de-facto standard
Copyright (C) 2011 Diego Torres Milano All rights reserved
17. types of test
by programmers for programmers
unit
in a programming language
JUnit is the de-facto standard
test objects in isolation
Copyright (C) 2011 Diego Torres Milano All rights reserved
18. types of test
by programmers for programmers
unit
in a programming language
JUnit is the de-facto standard
test objects in isolation
in a repeatable way
Copyright (C) 2011 Diego Torres Milano All rights reserved
19. types of test
by programmers for programmers
unit
in a programming language
JUnit is the de-facto standard
test objects in isolation
in a repeatable way
usually rely on mock objects
Copyright (C) 2011 Diego Torres Milano All rights reserved
20. types of test
tests
unit
functional
performance
integration
Copyright (C) 2011 Diego Torres Milano All rights reserved
21. types of test
functional
Copyright (C) 2011 Diego Torres Milano All rights reserved
22. types of test
by business & QA people functional
Copyright (C) 2011 Diego Torres Milano All rights reserved
23. types of test
by business & QA people functional
in a business domain language
Copyright (C) 2011 Diego Torres Milano All rights reserved
24. types of test
by business & QA people functional
in a business domain language
test completeness & correctness
Copyright (C) 2011 Diego Torres Milano All rights reserved
25. types of test
by business & QA people functional
in a business domain language
test completeness & correctness
BDD has gained some popularity
Copyright (C) 2011 Diego Torres Milano All rights reserved
26. types of test
by business & QA people functional
in a business domain language
test completeness & correctness
BDD has gained some popularity
FitNesse can help
Copyright (C) 2011 Diego Torres Milano All rights reserved
27. types of test
tests
unit
functional
performance
integration
Copyright (C) 2011 Diego Torres Milano All rights reserved
28. types of test
integration
Copyright (C) 2011 Diego Torres Milano All rights reserved
29. types of test
how components work together integration
Copyright (C) 2011 Diego Torres Milano All rights reserved
30. types of test
how components work together integration
modules have been unit tested
Copyright (C) 2011 Diego Torres Milano All rights reserved
31. types of test
how components work together integration
modules have been unit tested
android components need integration
with the system
Copyright (C) 2011 Diego Torres Milano All rights reserved
32. types of test
how components work together integration
modules have been unit tested
android components need integration
with the system
testing framework facilitates
integration
Copyright (C) 2011 Diego Torres Milano All rights reserved
33. types of test
tests
unit
functional
performance
integration
Copyright (C) 2011 Diego Torres Milano All rights reserved
35. types of test
measure performance in a
performance repeatable way
Copyright (C) 2011 Diego Torres Milano All rights reserved
36. types of test
measure performance in a
performance repeatable way
if cannot be measure cannot be
improved
Copyright (C) 2011 Diego Torres Milano All rights reserved
37. types of test
measure performance in a
performance repeatable way
if cannot be measure cannot be
improved
premature optimization does more
harm than good
Copyright (C) 2011 Diego Torres Milano All rights reserved
38. types of test
measure performance in a
performance repeatable way
if cannot be measure cannot be
improved
premature optimization does more
harm than good
measure-change-measure
Copyright (C) 2011 Diego Torres Milano All rights reserved
39. types of test
tests
unit
functional
performance
integration
Copyright (C) 2011 Diego Torres Milano All rights reserved
40. class diagram
Assert
<<iface>>
TestCase
Test
InstrumentationTestCase AndroidTestCase
ActivityInstrumentationTestCase2
ActivityUnitTestCase
Copyright (C) 2011 Diego Torres Milano All rights reserved
42. InstrumentationTestCase
instrumentation instantiated
before application
Copyright (C) 2011 Diego Torres Milano All rights reserved
43. InstrumentationTestCase
instrumentation instantiated
before application
allows for monitoring
interaction
Copyright (C) 2011 Diego Torres Milano All rights reserved
44. InstrumentationTestCase
instrumentation instantiated
before application
allows for monitoring
interaction
send keys and input events
Copyright (C) 2011 Diego Torres Milano All rights reserved
45. InstrumentationTestCase
instrumentation instantiated
before application
allows for monitoring
interaction
send keys and input events
manual lifecycle
Copyright (C) 2011 Diego Torres Milano All rights reserved
46. InstrumentationTestCase
instrumentation instantiated
before application
allows for monitoring
interaction
send keys and input events
manual lifecycle
direct or indirect base
class of other tests
Copyright (C) 2011 Diego Torres Milano All rights reserved
47. class diagram
Assert
<<iface>>
TestCase
Test
InstrumentationTestCase AndroidTestCase
ActivityInstrumentationTestCase2
ActivityUnitTestCase
Copyright (C) 2011 Diego Torres Milano All rights reserved
49. ActivityUnitTestCase
isolated testing of single
Activity
Copyright (C) 2011 Diego Torres Milano All rights reserved
50. ActivityUnitTestCase
isolated testing of single
Activity
minimal connection to
the system
Copyright (C) 2011 Diego Torres Milano All rights reserved
51. ActivityUnitTestCase
isolated testing of single
Activity
minimal connection to
the system
uses mocks for
dependencies
Copyright (C) 2011 Diego Torres Milano All rights reserved
52. ActivityUnitTestCase
isolated testing of single
Activity
minimal connection to
the system
uses mocks for
dependencies
some Activity methods
should not be called
Copyright (C) 2011 Diego Torres Milano All rights reserved
53. class diagram
Assert
<<iface>>
TestCase
Test
InstrumentationTestCase AndroidTestCase
ActivityInstrumentationTestCase2
ActivityUnitTestCase
Copyright (C) 2011 Diego Torres Milano All rights reserved
58. ActivityInstrumentationTestCase2
functional
testing of a single Activity
has access to Instrumentation
creates the AUT using system
infrastructure
custom intent can be provided
Copyright (C) 2011 Diego Torres Milano All rights reserved
59. class diagram
Assert
<<iface>>
TestCase
Test
InstrumentationTestCase AndroidTestCase
ActivityInstrumentationTestCase2
ActivityUnitTestCase
Copyright (C) 2011 Diego Torres Milano All rights reserved
61. access to Context AndroidTestCase
Copyright (C) 2011 Diego Torres Milano All rights reserved
62. access to Context AndroidTestCase
access to Resources
Copyright (C) 2011 Diego Torres Milano All rights reserved
63. access to Context AndroidTestCase
access to Resources
base class for Application, Provider
and Service test cases
Copyright (C) 2011 Diego Torres Milano All rights reserved
64. access to Context AndroidTestCase
access to Resources
base class for Application, Provider
and Service test cases
Context stored in mContext field
Copyright (C) 2011 Diego Torres Milano All rights reserved
65. access to Context AndroidTestCase
access to Resources
base class for Application, Provider
and Service test cases
Context stored in mContext field
can start more than one Activity
Copyright (C) 2011 Diego Torres Milano All rights reserved
66. class diagram
Assert
<<iface>>
TestCase
Test
InstrumentationTestCase AndroidTestCase
ActivityInstrumentationTestCase2
ActivityUnitTestCase
Copyright (C) 2011 Diego Torres Milano All rights reserved
68. test driven development advantages:
•the tests are written
one way or another
•developers take more
responsibility for the
quality of their work
Copyright (C) 2011 Diego Torres Milano All rights reserved
69. test driven development advantages:
•the tests are written
one way or another
•developers take more
responsibility for the
quality of their work
strategy of writing tests along development
Copyright (C) 2011 Diego Torres Milano All rights reserved
70. test driven development advantages:
•the tests are written
one way or another
•developers take more
responsibility for the
quality of their work
strategy of writing tests along development
test cases written prior to the code
Copyright (C) 2011 Diego Torres Milano All rights reserved
71. test driven development advantages:
•the tests are written
one way or another
•developers take more
responsibility for the
quality of their work
strategy of writing tests along development
test cases written prior to the code
single test added, then the code to satisfy it
Copyright (C) 2011 Diego Torres Milano All rights reserved
72. activity diagram
design decisions are
taken in single steps
and finally the code
write test satisfying the tests is
improved by
refactoring it
run
[fails]
code
[passes]
refactor
Copyright (C) 2011 Diego Torres Milano All rights reserved
73. temperature converter
Title
celsius
100
autoupdate
32
fahrenheit
keyboard
Copyright (C) 2011 Diego Torres Milano All rights reserved
75. requirements
converts between temperature
units
one temperature is entered and
the other is updated
error is displayed in the field
right aligned, 2 decimal digits
entry fields start empty
Copyright (C) 2011 Diego Torres Milano All rights reserved
77. understanding
requirements
to write a test you must understand the
requirement
Copyright (C) 2011 Diego Torres Milano All rights reserved
78. understanding
requirements
to write a test you must understand the
requirement
destination is quickly identified
Copyright (C) 2011 Diego Torres Milano All rights reserved
79. understanding
requirements
to write a test you must understand the
requirement
destination is quickly identified
if requirement change, changing the
corresponding test helps verify it
Copyright (C) 2011 Diego Torres Milano All rights reserved
80. github
$ mkdir myworkdir
$ cd myworkdir
$ git clone git@github.com:dtmilano/
TemperatureConverter.git
$ git clone git://github.com/dtmilano/
TemperatureConverterTests.git
Copyright (C) 2011 Diego Torres Milano All rights reserved
81. creating the
main project
TemperatureConverter uses
conventional settings
Copyright (C) 2011 Diego Torres Milano All rights reserved
82. creating the
main project
TemperatureConverter uses
conventional settings
Copyright (C) 2011 Diego Torres Milano All rights reserved
83. creating the test
project
Automatically selected values
for TemperatureConverterTest
project
Copyright (C) 2011 Diego Torres Milano All rights reserved
84. creating the test
case
Use:
ActivityInstrumentationTestCase2
as the base class
TemperatureConverterActivity as
the class under test
Copyright (C) 2011 Diego Torres Milano All rights reserved
85. warning
due to the
parameterized base
class
creating the test
case
Use:
ActivityInstrumentationTestCase2
as the base class
TemperatureConverterActivity as
the class under test
Copyright (C) 2011 Diego Torres Milano All rights reserved
86. constructor
/**
* Constructor
* @param name
*/
public TemperatureConverterActivityTests(String name) {
super(TemperatureConverterActivity.class);
setName(name);
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
87. fixture
protected void setUp(String name) throws Exception {
super.setUp();
mActivity = getActivity(); reference the
assertNotNull(mActivity); main package
mCelsius = (EditText)mActivity.findViewById(com...);
assertNotNull(mCelsius);
mFahrenheit = (EditText)mActivity.findViewById(com...);
assertNotNull(mFahrenheit);
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
89. ui tests: visibility
@SmallTest
public void testFieldsOnScreen() {
final View origin =
mActivity.getWindow().getDecorView();
ViewAsserts.assertOnScreen(origin, mCelsius);
ViewAsserts.assertOnScreen(origin, mFahrenheit);
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
90. ui tests: alignment
@SmallTest
public void testAlignment() {
! ! ViewAsserts.assertRightAligned(mCelsius,
mFahrenheit);
! ! ViewAsserts.assertLeftAligned(mCelsius,
mFahrenheit);
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
91. ui tests: initialization
@SmallTest
public void testFieldsShouldStartEmpty() {
! ! assertTrue("".equals(mCelsius.getText()
.toString()));
! ! assertTrue("".equals(mFahrenheit.getText()
.toString()));
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
92. ui tests: justification
@SmallTest
public void testJustification() {
! ! final int expected =
Gravity.RIGHT|Gravity.CENTER_VERTICAL;
! ! assertEquals(expected,
mCelsius.getGravity());
! ! assertEquals(expected,
mFahrenheit.getGravity());
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
93. running the tests
video plays on
click >>>
Copyright (C) 2011 Diego Torres Milano All rights reserved
94. running the tests
video plays on
click >>>
Copyright (C) 2011 Diego Torres Milano All rights reserved
95. gravity
add right and
center_vertical gravity
for celsius and
fahrenheit
Copyright (C) 2011 Diego Torres Milano All rights reserved
96. gravity
add right and
center_vertical gravity
for celsius and
fahrenheit
Copyright (C) 2011 Diego Torres Milano All rights reserved
97. running the tests
video plays on
click >>>
Copyright (C) 2011 Diego Torres Milano All rights reserved
98. running the tests
video plays on
click >>>
Copyright (C) 2011 Diego Torres Milano All rights reserved
99. temperature conversion
! @UiThreadTest
! public void testFahrenheitToCelsiusConversion() {
! ! mCelsius.clear();
! ! mFahrenheit.clear(); errors are
underlined in red
! ! final double f = 32.5;
! ! mFahrenheit.requestFocus();
! ! mFahrenheit.setNumber(f);
! ! mCelsius.requestFocus();
! ! final double expected =
TemperatureConverter.fahrenheitToCelsius(f);
! ! final double actual = mCelsius.getNumber();
! ! final double delta = Math.abs(expected - actual);
! ! assertTrue(delta < 0.005);
! }
Copyright (C) 2011 Diego Torres Milano All rights reserved
100. temperature conversionrun in the ui
! @UiThreadTest thread
! public void testFahrenheitToCelsiusConversion() {
! ! mCelsius.clear();
! ! mFahrenheit.clear(); errors are
underlined in red
! ! final double f = 32.5;
! ! mFahrenheit.requestFocus();
! ! mFahrenheit.setNumber(f);
! ! mCelsius.requestFocus();
! ! final double expected =
TemperatureConverter.fahrenheitToCelsius(f);
! ! final double actual = mCelsius.getNumber();
! ! final double delta = Math.abs(expected - actual);
! ! assertTrue(delta < 0.005);
! }
Copyright (C) 2011 Diego Torres Milano All rights reserved
101. temperature conversionrun in the ui
! @UiThreadTest thread
! public void testFahrenheitToCelsiusConversion() {
specialized
class
! ! mCelsius.clear();
! ! mFahrenheit.clear(); errors are
underlined in red
! ! final double f = 32.5;
! ! mFahrenheit.requestFocus();
! ! mFahrenheit.setNumber(f);
! ! mCelsius.requestFocus();
! ! final double expected =
TemperatureConverter.fahrenheitToCelsius(f);
! ! final double actual = mCelsius.getNumber();
! ! final double delta = Math.abs(expected - actual);
! ! assertTrue(delta < 0.005);
! }
Copyright (C) 2011 Diego Torres Milano All rights reserved
102. temperature conversion run in the ui
! @UiThreadTest thread
! public void testFahrenheitToCelsiusConversion() {
specialized
class
! ! mCelsius.clear();
! ! mFahrenheit.clear(); errors are
underlined in red
! ! final double f = 32.5;
! ! mFahrenheit.requestFocus();
! ! mFahrenheit.setNumber(f); converter
! ! mCelsius.requestFocus(); helper
! ! final double expected =
TemperatureConverter.fahrenheitToCelsius(f);
! ! final double actual = mCelsius.getNumber();
! ! final double delta = Math.abs(expected - actual);
! ! assertTrue(delta < 0.005);
! }
Copyright (C) 2011 Diego Torres Milano All rights reserved
103. EditNumber class
EditNumber class
extends EditText
Copyright (C) 2011 Diego Torres Milano All rights reserved
104. TemperatureCon
verter
TemperatureConverter
is a helper class
Copyright (C) 2011 Diego Torres Milano All rights reserved
105. exception
java.lang.ClassCastException:
android.widget.EditText at
com.example.i2at.tc.test.
TemperatureConverterActivityTests.setUp
(TemperatureConverterActivityTests.java: 44)
Copyright (C) 2011 Diego Torres Milano All rights reserved
106. exception
java.lang.ClassCastException:
android.widget.EditText at
com.example.i2at.tc.test.
TemperatureConverterActivityTests.setUp
(TemperatureConverterActivityTests.java: 44)
44:!! mCelsius = (EditNumber)
mActivity.findViewById(
com.example.i2at.tc.R.id.celsius);
Copyright (C) 2011 Diego Torres Milano All rights reserved
107. layout
<com.example.i2at.tc.EditNumber
android:layout_height="wrap_content"
! ! android:layout_width="match_parent"
android:inputType="numberDecimal"
! ! android:id="@+id/celsius"
android:gravity="right|center_vertical">
! ! <requestFocus />
</com.example.i2at.tc.EditNumber>
Copyright (C) 2011 Diego Torres Milano All rights reserved
108. running the tests
Copyright (C) 2011 Diego Torres Milano All rights reserved
109. running the tests
what?
Copyright (C) 2011 Diego Torres Milano All rights reserved
110. celsius to fahrenheit
Fahrenheit
150
112.5
75
37.5
0
-37.5
-75
-40 -30 -20 -10 0 10 20 30 40
Celsius
Copyright (C) 2011 Diego Torres Milano All rights reserved
111. celsius to fahrenheit
Fahrenheit
150
112.5
75
f = 9/5 * c + 32
37.5
0
c = (f-32) * 5/9
-37.5
-75
-40 -30 -20 -10 0 10 20 30 40
Celsius
Copyright (C) 2011 Diego Torres Milano All rights reserved
112. converter
public class TemperatureConverter {
! public static double fahrenheitToCelsius(double f) {
/ TODO Auto-generated method stub
/
! ! return 0;
! }
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
113. TemperatureConv
erterTests
Test case as base class
create method stubs
TemperatureConverter as
CUT
Copyright (C) 2011 Diego Torres Milano All rights reserved
114. method stubs
select the methods you want
stubs created for
Copyright (C) 2011 Diego Torres Milano All rights reserved
115. conversion test
public void testFahrenheitToCelsius() {
! ! for (double c: sConversionTableDouble.keySet()) {
! ! ! final double f = sConversionTableDouble.get(c);
! ! ! final double ca =
TemperatureConverter.fahrenheitToCelsius(f);
! ! ! final double delta = Math.abs(ca - c);
! ! ! assertTrue(delta < 0.005);
! ! }
! }
Copyright (C) 2011 Diego Torres Milano All rights reserved
118. run the tests
this
assertion fails
Copyright (C) 2011 Diego Torres Milano All rights reserved
119. creating test
case
use AndroidTestCase as base
class
use EditNumber as CUT
Copyright (C) 2011 Diego Torres Milano All rights reserved
120. method stubs
select the Context constructor
select other methods
Copyright (C) 2011 Diego Torres Milano All rights reserved
121. test
public final void testClear() {
! ! final String value = "123.45";
! ! mEditNumber.setText(value);
! ! mEditNumber.clear();
! ! final String expected = "";
! ! final String actual =
mEditNumber.getText().toString();
! ! assertEquals(expected, actual);
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
122. implementation
public class EditNumber extends EditText {
/ ...
/
! public void clear() {
! ! setText("");
! }
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
123. test
public final void testSetNumber() {
! ! final double d = 123.45;
! ! mEditNumber.setNumber(d);
! ! final String expected = Double.toString(d);
! ! final String actual =
mEditNumber.getText().toString();
! ! assertEquals(expected, actual);
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
124. test
public final void testGetNumber() {
! ! final double expected = 123.45;
! ! mEditNumber.setNumber(expected);
! ! final double actual =
mEditNumber.getNumber();
! ! assertEquals(expected, actual);
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
125. implementation
public class EditNumber extends EditText {
/ ...
/
! public void getNumber() {
final String s = getText().toString();
if ( "".equals(s) ) {
return Double.NaN;
}
! ! return Double.valueOf(s);
! }
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
126. run the tests NO video
Copyright (C) 2011 Diego Torres Milano All rights reserved
127. what’s the problem ?
Copyright (C) 2011 Diego Torres Milano All rights reserved
128. what’s the problem ?
clear() works
requestFocus() works
setNumber() works
fahrenheitToCelsius() works
getNumber() works
so ?
Copyright (C) 2011 Diego Torres Milano All rights reserved
129. temperature converter
Title
celsius
100
32
fahrenheit
keyboard
Copyright (C) 2011 Diego Torres Milano All rights reserved
130. temperature converter
Title
celsius
100
autoupdate
32
fahrenheit
keyboard
Copyright (C) 2011 Diego Torres Milano All rights reserved
131. TemperatureChan
geWatcher
create it as an inner class
implements TextWatcher
inherited abstract methods
create 2 fields mSource &
mDest
Copyright (C) 2011 Diego Torres Milano All rights reserved
132. generate
constructor
use the fields
omit call to super()
Copyright (C) 2011 Diego Torres Milano All rights reserved
133. the watcher
public abstract class TemperatureChangeWatcher
implements TextWatcher {
! ! private EditNumber mSource;
! ! private EditNumber mDest;
! !
! ! public TemperatureChangeWatcher(
EditNumber source, EditNumber dest) {
! ! ! this.mSource = source;
! ! ! this.mDest = dest;
! ! }
/ ...
/
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
134. on text changed
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
! if ( !mDest.hasWindowFocus() || mDest.hasFocus() || s == null ) return;
! final String str = s.toString();
! if ( "".equals(str) ) {
! ! mDest.setText(""); return;
! }
! try {
! ! final double result = convert(Double.parseDouble(str));
! ! mDest.setNumber(result);
! }
! catch (NumberFormatException e) {
! ! / WARNING: this is thrown while a number is entered, for example just a '-'
/
! }
! catch (Exception e) {
! ! mSource.setError("ERROR: " + e.getLocalizedMessage());
! }
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
135. on text changed
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
! if ( !mDest.hasWindowFocus() || mDest.hasFocus() || s == null ) return;
! final String str = s.toString();
! if ( "".equals(str) ) {
! ! mDest.setText(""); return;
we should
! }
define it
! try {
! ! final double result = convert(Double.parseDouble(str));
! ! mDest.setNumber(result);
! }
! catch (NumberFormatException e) {
! ! / WARNING: this is thrown while a number is entered, for example just a '-'
/
! }
! catch (Exception e) {
! ! mSource.setError("ERROR: " + e.getLocalizedMessage());
! }
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
136. abstract convert method
public abstract class TemperatureChangeWatcher
implements TextWatcher {
//...
protected abstract double convert(double temp);
//...
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
137. find views
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mCelsius =
(EditNumber) findViewById(R.id.celsius);
mFahrenheit =
(EditNumber) findViewById(R.id.fahrenheit);
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
138. add change listeners
@Override
public void onCreate(Bundle savedInstanceState) {
/ ...
/
mCelsius.addTextChangedListener(
we should
new TemperatureChangeWatcher(mCelsius, mFahrenheit) {
create it
! ! ! @Override protected double convert(double temp) {
! ! ! ! return TemperatureConverter.celsiusToFahrenheit(temp);
! ! ! }!
});
mFahrenheit.addTextChangedListener(
new TemperatureChangeWatcher(mFahrenheit, mCelsius) {
! ! ! @Override protected double convert(double temp) {
! ! ! ! return TemperatureConverter.fahrenheitToCelsius(temp);
! ! ! }
});
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
139. add conversion
public class TemperatureConverter {
! public static double fahrenheitToCelsius(double f) {
! ! return (f-32) * 5/9.0;
! }
! public static double celsiusToFahrenheit(double c) {
! ! / TODO Auto-generated method stub
/
! ! return 0;
! }
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
140. adding test
public class TemperatureConverterTests extends TestCase {
/ ...
/
! /**
! * Test method for {@link TemperatureConverter#fahrenheitToCelsius(double)}.
! */
! public void testCelsiusToFahrenheit() {
! ! for (double c: sConversionTableDouble.keySet()) {
! ! ! final double f = sConversionTableDouble.get(c);
! ! ! final double fa = TemperatureConverter.celsiusToFahrenheit(c);
! ! ! final double delta = Math.abs(fa - f);
! ! ! assertTrue("delta=" + delta + " for f=" + f + " fa=" + fa, delta < 0.005);
! ! }
! }
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
141. running the tests
Copyright (C) 2011 Diego Torres Milano All rights reserved
142. implementing conversion
public class TemperatureConverter {
! public static double fahrenheitToCelsius(double f) {
! ! return (f-32) * 5/9.0;
! }
! public static double celsiusToFahrenheit(double c) {
! ! return 9/5.0 * c + 32;
! }
}
Copyright (C) 2011 Diego Torres Milano All rights reserved
143. running the tests
Copyright (C) 2011 Diego Torres Milano All rights reserved
146. code coverage
measures the amount of source code tested
Copyright (C) 2011 Diego Torres Milano All rights reserved
147. code coverage
measures the amount of source code tested
android relies on emma (http://emma.sf.net)
Copyright (C) 2011 Diego Torres Milano All rights reserved
148. code coverage
measures the amount of source code tested
android relies on emma (http://emma.sf.net)
supported coverage types:
class
method
line
block
Copyright (C) 2011 Diego Torres Milano All rights reserved
152. coverage report
overall coverage summary
overall stats summary
coverage breakdown by package
Copyright (C) 2011 Diego Torres Milano All rights reserved
153. building with ant
disable project’s Build Automatically in Eclipse
convert project to ant
$ android update project --path $PWD --name
TemperatureConverter --target android-10
$ android update test-project --main ../
TemperatureConverter --path $PWD
Copyright (C) 2011 Diego Torres Milano All rights reserved
154. run
configuration coverage
run build.xml as Ant build...
use coverage target
Copyright (C) 2011 Diego Torres Milano All rights reserved
155. ant 1.8
specify ant 1.8 home
Ant home...
Copyright (C) 2011 Diego Torres Milano All rights reserved
156. coverage
run build.xml coverage
coverage analysis report is generated
get coverage file
$ adb pull /data/data/com.example.i2at.tc/files/
coverage.ec coverage.ec
Copyright (C) 2011 Diego Torres Milano All rights reserved
170. requirements
converts between temperature
units
one temperature is entered and
the other is updated
error is displayed in the field
right aligned, 2 decimal digits
entry fields start empty
Copyright (C) 2011 Diego Torres Milano All rights reserved
172. continuous integration
agile technique for software engineering
received broad adoption in recent years
prevents “integration hell”
integrate changes frequently
Copyright (C) 2011 Diego Torres Milano All rights reserved
181. build dependency
these are the
TemperatureConverterTest
project options. This depends on
TemperatureConverter.
Copyright (C) 2011 Diego Torres Milano All rights reserved
185. xml test results
download xmlinstrumentationtestrunner.jar
replace instrumentation by
android:name="com.neenbedankt.android.test.
XMLInstrumentationTestRunner"
customize build.xml
Copyright (C) 2011 Diego Torres Milano All rights reserved
189. behavior driven
development
evolution of Test Driven Development
inclusion of business participant
common vocabulary
based on Neuro Linguistics Programming
Copyright (C) 2011 Diego Torres Milano All rights reserved
195. android application
testing guide
Copyright (C) 2011 Diego Torres Milano All rights reserved
196. android application
testing guide
Apply testing techniques and tools
• Learn the nuances of Unit and
Functional testing
• Understand different development
methodologies such as TDD and BDD
• Apply Continuous Integration
• Improve applications using
performance tests
• Expose your application to a wide
range of conditions
Copyright (C) 2011 Diego Torres Milano All rights reserved
Google CEO Larry Page&#x2019;s blog post announcing the news: Android now has a total of over 150 million activated devices worldwide. That number is up from 130 million handsets only a month ago. And they continue to sell at a rate of over 550,000 new activations a day (this stat had been previously announced). To add some context, Apple announced last month that it&#x2019;s sold 222 million iOS devices to date, including the iPod Touch, iPad, and iPhone.\n
We will be reviewing the main concepts behind testing and the techniques, frameworks, and tools available to deploy your testing strategy on Android.\nInitially, when Android was introduced by the end of 2007, there was very little support for testing on the platform, but with the latests SDK versions a complete test framework was introduced.\n\n
why: because bugs severely affect projects, killing them early saves project resources, also to grasp requirements\nwhat: the more you cover higher the expectations of finding bugs, coverage analysis helps\nwhen: the sooner the better, TDD, an agile component, helps in this area and forces you to face bugs earlier\nhow: applying the techniques and tools we will be revealing soon\n
why: because bugs severely affect projects, killing them early saves project resources, also to grasp requirements\nwhat: the more you cover higher the expectations of finding bugs, coverage analysis helps\nwhen: the sooner the better, TDD, an agile component, helps in this area and forces you to face bugs earlier\nhow: applying the techniques and tools we will be revealing soon\n
why: because bugs severely affect projects, killing them early saves project resources, also to grasp requirements\nwhat: the more you cover higher the expectations of finding bugs, coverage analysis helps\nwhen: the sooner the better, TDD, an agile component, helps in this area and forces you to face bugs earlier\nhow: applying the techniques and tools we will be revealing soon\n
why: because bugs severely affect projects, killing them early saves project resources, also to grasp requirements\nwhat: the more you cover higher the expectations of finding bugs, coverage analysis helps\nwhen: the sooner the better, TDD, an agile component, helps in this area and forces you to face bugs earlier\nhow: applying the techniques and tools we will be revealing soon\n
Testing can be implemented at any time in the development process. However, we will be promoting testing at an early stage of the development effort, even before the full set of requirements have been defined and the coding process has been started.\nThere are several types of test available depending on the object being tested. Regardless of its type, a test should verify a condition and return the result of this evaluation as a single Boolean value indicating success or failure.\n\n
Unit tests are software tests written by programmers for programmers in a programming language and they should isolate the component under test and be able to test it in a repeatable way.\n\n
Unit tests are software tests written by programmers for programmers in a programming language and they should isolate the component under test and be able to test it in a repeatable way.\n\n
Unit tests are software tests written by programmers for programmers in a programming language and they should isolate the component under test and be able to test it in a repeatable way.\n\n
Unit tests are software tests written by programmers for programmers in a programming language and they should isolate the component under test and be able to test it in a repeatable way.\n\n
Unit tests are software tests written by programmers for programmers in a programming language and they should isolate the component under test and be able to test it in a repeatable way.\n\n
Unit tests are software tests written by programmers for programmers in a programming language and they should isolate the component under test and be able to test it in a repeatable way.\n\n
Android (up to Android 2.3 Gingerbread) uses JUnit 3. This version doesn't use annotations and uses introspection to detect the tests.\n\n
In agile software development, functional or acceptance tests are usually created by business and Quality Assurance (QA) people and expressed in a business domain language. These are high level tests to test the completeness and correctness of a user requirement or feature.\nWe will be introducing FitNesse, a framework that can be integrated \n\n
In agile software development, functional or acceptance tests are usually created by business and Quality Assurance (QA) people and expressed in a business domain language. These are high level tests to test the completeness and correctness of a user requirement or feature.\nWe will be introducing FitNesse, a framework that can be integrated \n\n
In agile software development, functional or acceptance tests are usually created by business and Quality Assurance (QA) people and expressed in a business domain language. These are high level tests to test the completeness and correctness of a user requirement or feature.\nWe will be introducing FitNesse, a framework that can be integrated \n\n
In agile software development, functional or acceptance tests are usually created by business and Quality Assurance (QA) people and expressed in a business domain language. These are high level tests to test the completeness and correctness of a user requirement or feature.\nWe will be introducing FitNesse, a framework that can be integrated \n\n
In agile software development, functional or acceptance tests are usually created by business and Quality Assurance (QA) people and expressed in a business domain language. These are high level tests to test the completeness and correctness of a user requirement or feature.\nWe will be introducing FitNesse, a framework that can be integrated \n\n
\n
Integration tests are designed to test the way individual components work jointly. Modules that have been unit tested independently are now combined together to test the integration.\nUsually Android Activities require some integration with the system infrastructure to be able to run. They need the Activity lifecycle provided by the ActivityManager, and access to resources, filesystem, and databases.\n\n
Integration tests are designed to test the way individual components work jointly. Modules that have been unit tested independently are now combined together to test the integration.\nUsually Android Activities require some integration with the system infrastructure to be able to run. They need the Activity lifecycle provided by the ActivityManager, and access to resources, filesystem, and databases.\n\n
Integration tests are designed to test the way individual components work jointly. Modules that have been unit tested independently are now combined together to test the integration.\nUsually Android Activities require some integration with the system infrastructure to be able to run. They need the Activity lifecycle provided by the ActivityManager, and access to resources, filesystem, and databases.\n\n
Integration tests are designed to test the way individual components work jointly. Modules that have been unit tested independently are now combined together to test the integration.\nUsually Android Activities require some integration with the system infrastructure to be able to run. They need the Activity lifecycle provided by the ActivityManager, and access to resources, filesystem, and databases.\n\n
\n
And finally, Performance tests measure performance characteristics of the components in a repeatable way.\nAs is widely known, premature optimization does more harm than good, so it is better to clearly understand the impact of your changes on the overall performance.\n\n
And finally, Performance tests measure performance characteristics of the components in a repeatable way.\nAs is widely known, premature optimization does more harm than good, so it is better to clearly understand the impact of your changes on the overall performance.\n\n
And finally, Performance tests measure performance characteristics of the components in a repeatable way.\nAs is widely known, premature optimization does more harm than good, so it is better to clearly understand the impact of your changes on the overall performance.\n\n
And finally, Performance tests measure performance characteristics of the components in a repeatable way.\nAs is widely known, premature optimization does more harm than good, so it is better to clearly understand the impact of your changes on the overall performance.\n\n
Android provides a very advanced testing framework extending the industry standard JUnit with specific features suitable for implementing all of the testing strategies and types we mentioned before.\n\n
\n
Yellow: junit Green: android\n\n
The instrumentation framework is the foundation of the testing framework. Instrumentation controls the application under test and permits the injection of mock components required by the application to run. For example, you can create mock Contexts before the application starts and let the application use them.\nHas launchActivity and launchActivityWithIntent utility methods.\n
The instrumentation framework is the foundation of the testing framework. Instrumentation controls the application under test and permits the injection of mock components required by the application to run. For example, you can create mock Contexts before the application starts and let the application use them.\nHas launchActivity and launchActivityWithIntent utility methods.\n
The instrumentation framework is the foundation of the testing framework. Instrumentation controls the application under test and permits the injection of mock components required by the application to run. For example, you can create mock Contexts before the application starts and let the application use them.\nHas launchActivity and launchActivityWithIntent utility methods.\n
The instrumentation framework is the foundation of the testing framework. Instrumentation controls the application under test and permits the injection of mock components required by the application to run. For example, you can create mock Contexts before the application starts and let the application use them.\nHas launchActivity and launchActivityWithIntent utility methods.\n
The instrumentation framework is the foundation of the testing framework. Instrumentation controls the application under test and permits the injection of mock components required by the application to run. For example, you can create mock Contexts before the application starts and let the application use them.\nHas launchActivity and launchActivityWithIntent utility methods.\n
All interaction of the application with the surrounding environment can be controlled using this approach. You can also isolate your application in a restricted environment to be able to predict the results, forcing the values returned by some methods or mocking persistent and unchanged data for ContentProvider, databases, or even the filesystem content.\n
The following methods should not be called in this configuration - most of them will throw exceptions:\nstartActivityIfNeeded(), getCallingActivity(), getTaskId(), moveTaskToBack()\n\n
The following methods should not be called in this configuration - most of them will throw exceptions:\nstartActivityIfNeeded(), getCallingActivity(), getTaskId(), moveTaskToBack()\n\n
The following methods should not be called in this configuration - most of them will throw exceptions:\nstartActivityIfNeeded(), getCallingActivity(), getTaskId(), moveTaskToBack()\n\n
The following methods should not be called in this configuration - most of them will throw exceptions:\nstartActivityIfNeeded(), getCallingActivity(), getTaskId(), moveTaskToBack()\n\n
\n
\n
\n
\n
\n
\n
This class can be used as a base class for general purpose Android test cases.\nUse this class when you need access to an Activity Context like Resources, databases, or files in the filesystem. Context is stored as a field in this class conveniently named mContext and can be used inside the tests if needed.\nTests based on this class can start more than one Activity using Context.startActivity().\n\n
This class can be used as a base class for general purpose Android test cases.\nUse this class when you need access to an Activity Context like Resources, databases, or files in the filesystem. Context is stored as a field in this class conveniently named mContext and can be used inside the tests if needed.\nTests based on this class can start more than one Activity using Context.startActivity().\n\n
This class can be used as a base class for general purpose Android test cases.\nUse this class when you need access to an Activity Context like Resources, databases, or files in the filesystem. Context is stored as a field in this class conveniently named mContext and can be used inside the tests if needed.\nTests based on this class can start more than one Activity using Context.startActivity().\n\n
This class can be used as a base class for general purpose Android test cases.\nUse this class when you need access to an Activity Context like Resources, databases, or files in the filesystem. Context is stored as a field in this class conveniently named mContext and can be used inside the tests if needed.\nTests based on this class can start more than one Activity using Context.startActivity().\n\n
This class can be used as a base class for general purpose Android test cases.\nUse this class when you need access to an Activity Context like Resources, databases, or files in the filesystem. Context is stored as a field in this class conveniently named mContext and can be used inside the tests if needed.\nTests based on this class can start more than one Activity using Context.startActivity().\n\n
\n
\n
Briefly, Test Driven Development is the strategy of writing tests along the development process. These test cases are written in advance of the code that is supposed to satisfy them.\nThis contrasts with other approaches to the development process where the tests are written at the end when all the coding has been done.\n\n
Briefly, Test Driven Development is the strategy of writing tests along the development process. These test cases are written in advance of the code that is supposed to satisfy them.\nThis contrasts with other approaches to the development process where the tests are written at the end when all the coding has been done.\n\n
Briefly, Test Driven Development is the strategy of writing tests along the development process. These test cases are written in advance of the code that is supposed to satisfy them.\nThis contrasts with other approaches to the development process where the tests are written at the end when all the coding has been done.\n\n
Design decisions are taken in single steps and finally the code satisfying the tests is improved by refactoring it.\nWe start our development process with writing a test case. This apparently simple process will put some machinery to work inside our heads.\n\n
\n
\n
\n
\n
\n
\n
The main advantage I've seen so far is that you focus your destination quickly and is much difficult to divert implementing options in your software that will never be used.\nTest Driven Development could not be indiscriminately applied to any project. I think that, as well as any other technique you should use your judgment and expertise to recognize where it can be applied.\n\n\n
The main advantage I've seen so far is that you focus your destination quickly and is much difficult to divert implementing options in your software that will never be used.\nTest Driven Development could not be indiscriminately applied to any project. I think that, as well as any other technique you should use your judgment and expertise to recognize where it can be applied.\n\n\n
The main advantage I've seen so far is that you focus your destination quickly and is much difficult to divert implementing options in your software that will never be used.\nTest Driven Development could not be indiscriminately applied to any project. I think that, as well as any other technique you should use your judgment and expertise to recognize where it can be applied.\n\n\n
git read-only access.\nDon&#x2019;t forget to adapt local.properties.template to suit your environment needs if using ant.\nImport into Eclipse.\n
Our examples will revolve around an extremely simple Android sample project. It doesn't try to show all the fancy Android features but focuses on testing and gradually building the application from the test, applying the concepts learned before.\n
The creation of the test project is displayed in this screenshot. All values will be selected for you based on your previous entries.\n\n
Proceed with creating the first test by selecting the main test package name com.example.aatg.tc.test in Eclipse's Package Explorer, and then right-click on it. Select New | JUnit Test Case.\nJUnit 3 is the version supported by Android. Always use this option.\n
We now notice that our automatically generated class has some errors we need to fix before running. Otherwise the errors will prevent the test from compiling.\nFirst we should add the missing imports, using the shortcut Shift+Ctrl+O.\nSecond, the problem we need to fix is the no argument constructor.\n\n
We can start creating our test fixture (well known state defined as a baseline) by populating the setUp method with the elements we need in our tests. Almost unavoidable, in this case, is the use of the Activity under test, so let's prepare for the situation and add it to the fixture.\nThe ActivityInstrumentationTestCase2.getActivity() method has a side effect. If the Activity under test is not running, it is started.\n\n
\n
\n
\n
\n
\n
Video plays on click >>>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
We define convert as an abstract method, to invoke the corresponding convert method depending on the conversion needed\n
We will be creating anonymous classes when we assign the watchers\n
\n
\n
\n
\n
\n
\n
\n
\n
Code coverage is a measure used in software testing that describes the amount of source code that was actually tested by the test suite and to what degree following some criteria.\n\n
Code coverage is a measure used in software testing that describes the amount of source code that was actually tested by the test suite and to what degree following some criteria.\n\n
Code coverage is a measure used in software testing that describes the amount of source code that was actually tested by the test suite and to what degree following some criteria.\n\n
overall summary: the summary for all classes\noverall stats summary: the statistics of the coverage (i.e. how many packages)\ncoverage breakdown: coverage for particular packages\n
overall summary: the summary for all classes\noverall stats summary: the statistics of the coverage (i.e. how many packages)\ncoverage breakdown: coverage for particular packages\n
overall summary: the summary for all classes\noverall stats summary: the statistics of the coverage (i.e. how many packages)\ncoverage breakdown: coverage for particular packages\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
The original article was written by Martin Fowler back in 2000, and describes the experience of putting together Continuous Integration on a large software project.\nContinuous Integration has received a broad adoption in recent years, and a proliferation of commercial tools and Open Source projects is a clear demonstration of its success.\n\n
Continuous Integration is one agile technique for software engineering that aims to improve the software quality and to reduce the time taken to integrate changes by continuously applying integration and testing frequently, opposed to the more traditional approach of integrating and testing by the end of the development cycle.\n\n
The most common practice is to trigger the build process after every commit to the source code repository, this practice also implies other requirements, beside the source code being maintained by a Version Control System.\nBuilds should be automated by running a single command.\nThe build should be self tested,\n