. (dot) character, regular expressions, 84
/ (slash) character, regular expressions, 84
$ (dollar sign), regular expressions, 84
AAA (arrange, act, and assert) test structure, 48, 66
Abstract Factory pattern
testing data-driven execution, 33
Access levels
adjusting visibility by changing, 109–111
adjusting visibility by packaging tests, 105–107
designating with test-only interfaces, 111–112
using reflection to coerce access, 114–115, 126
AccessibleObject
class, 115
Agile development
Automated Testing Triangle, 9
Annotations
simplifying error condition tests with, 131
in test naming conventions, 49–50
Anonymous entities, difficult to test, 113
Anonymous inner classes, Java
in error injection, 98
API specification, testing interfaces using, 146
Appender
testing code using custom logging, 161–163
in thread-synchronization, 182–184
Approach to testing, 41
Architectural layers, influencing scope, 24
Assertion failures, using unique values, 57
Attribute encapsulation
accessing with getter methods, 64
resulting in coupling, 53
testing getters and setters, 66–67
Attributes
adjusting visibility, 105
encapsulation resulting in coupling, 45–46
in exception design, 141
exception-based, 134–135, 137–138, 141
hiding for security, 55
in naming conventions, 49
in state verification tests, 27
tests that pass when lying about, 19
tests verifying individual, 45
Authentication, expiration boundary test for, 72–75
Automated testing. See Starting
Automated Testing Triangle, 9, 28
Automotive engineers, 4
Basics, testing
bootstrapping constructors, 63–66
encapsulating and overriding, 72–75
testing simple getters and setters, 66–67
verification by injection, 77–79
Behavioral encapsulation, 39–40
Behavioral testing
JavaScript example of, 27
purpose of regression test, 41
Black-box tests
testing transparency, 41
BlockingQueue
interface, 185
Bootstrapping
testing simple getters and setters, 66–67
Bottom-up testing, 213
Boundary conditions test, 31–32
Buffered I/O classes, 39
Bugs
avoiding test code in production, 52
code coverage and, 12
eliminating rework of, 5
preventing rather than catching, 8
in threads, 167
C
dynamic-binding and reflection, 34
function pointers, 151
implementing callbacks, 151
static analysis tool for, 7
verifying interface definition, 146
C++
access level changes, 109
context mutability, 21
declaring entities in nested classes, 112
dynamic-binding and reflection, 34
error condition verification, 134
error condition verification in, 137
implementing callbacks, 151–153
nested anonymous enumerations, 70
pointer-to-member function, 151, 153
static analysis tool for, 7
verifying interface definition, 146
Callable
interface, Java
in common lock synchronization, 177–178, 180
directly testing thread task, 173
Catch
clause, verifying exception type, 131–132
Characterization testing
legacy code and economics of, 28
mess of code requiring, 25
scaling up legacy code, 215
Checkstyle, 7
Chunking, 127
Civil engineers, 4
Clarity of intention, in minimalist approaches, 18
Class
refactoring to enhance testability, 108–109
testing Singleton’s purpose, 123–127
Class::Std module, Perl, 109, 116–117
Cleanliness of code, and scope of testing, 24–25
Clover, 14
Code
avoid testing the framework, 58–60
simplifying tests by deleting, 58
testing untested. See Legacy JavaScript
thread-safe, 167
Code checker constraints, in unit testing, 10
Code coverage
avoid testing code in production with, 52
as guide, 13
removing code in testing to increase, 58
unit testing with, 7
Code generation tools, 7, 59–60
Code smell
concurrency, 169
defined, 7
encountering through your tests, 128
CodeCover, 14
CodeMash, 3
Coincidental equality, 73, 82, 86
Coincidental similarity, 82
Collaborators
Test Doubles and, 100
Command-line debuggers, 190
Comments, relaxing visibility with, 111
Common lock synchronization, 176–181
Complete verification, testing for, 55
Component level
cost of integration tests at, 28
testing purpose of code at, 25
Conceptual framework, for testing, 25–26
Concurrency
code smell, 169
monkey test for, 189
Connection
collaborator, 99–100, 102
Constants
exact verification of strings with shared, 85–87
exact verification with formatted results using, 88–89
limitations of, 88
testing constructors using shared, 67–70
Constructor injection, 148–149
test-driven Java, 196–197, 200
testing Singleton with relaxed access to, 125–127
testing using shared constants, 67–70
Containment
false-positive weaknesses of, 88
verification of strings by, 81–83
Context, differentiating exceptions, 137–138
Continuous integration, in software craftsmanship, 7–8
Cooperative multitasking, in parallel programming, 166
concept of, 53
defined, 42
factories as test seams and, 159
inputs to outputs in tests, 48–49
less likely with small tests, 55–56
mocks introducing high degree of, 201
null object implementations and, 103
Coverage
testing alternate paths, 30
Craftsmanship
practices supporting software, 6–8
role in first-time quality, 3–5
unit testing for coverage, 10–15
unit testing under code checker constraints, 10
Critical section of code, read-write race conditions, 168
Cucumber tool, 200
Curl
tool. See Test-driven Java
Custom logging appender, 161–163
Data path coverage, 14
Data permutations tests
run-time and dynamic binding, 33–35
Data type injection, overriding encapsulation, 91–94
Data-driven execution
testing for permutations, 32–33
unit testing for coverage, 11
DataProvider
parameter, @Test
, 93–94
Deadlocks, 169
Debugger
Java code using log4j as seam for, 160–163
reproducing race conditions, 171–172
Declarations, runtime exceptions, 134
Declarative scope changing, adjusting visibility, 116–117
Defects, testing for, 35
Def-use chains, 14
Deleting code, 58
Delimiters, naming conventions, 50
Depended-On Components (DOCs), 77
Dependencies. See Coupling
Dependency injection
as alternative to Singleton pattern, 122
registries providing indirect form of, 155
synchronization through, 181–184
test-driven Java, 200
Design and testability
behavioral encapsulation, 39–40
dimensions of testing, 41
encapsulation, observability and, 42
overview of, 37
representational encapsulation, 38–39
Devel::Cover, 14
Difficult-to-test designs, 122
Dimensions of testing, 41
Direct calls, using existing seams, 146–147
Direct testing, adjusting visibility, 75–77
DNS (Domain Name System), 32
DOCs (Depended-On Components), 77
Documentation, relaxing visibility with, 111
Dollar sign ($), regular expressions, 84
Domain Name System (DNS), 32
Dot (.) character, regular expressions, 84
Dp4j tool, Java reflection, 115
Dynamic binding, reflection-based code, 33–35
Dynamic dispatch, unit test for coverage, 12
EasyMock
in dependency injection, 149
overview of, 100
registries and, 155
Economics of testing types, 28
Encapsulation
breaking via direct testing, 75–77
from coupling in unit testing, 53
design paradigms and, 37
observability, testing and, 42
Encapsulation and override, 72–75
Encapsulation and override variations
encapsulating loop conditions, 94–96
overview of, 91
replacing collaborators, 98–100
using existing no-op classes, 101–103
practices supporting craftsmanship, 5–10
unit testing for coverage, 10–15
unit testing under code checker constraints, 10
Errno
values, verifying error conditions, 129–130
checking return value, 129–130
overview of, 129
verifying exception instance, 137–140
verifying exception message, 132–134
verifying exception payload, 134–137
verifying exception type, 130–132
Error conditions, null values indicating, 101
Error injection, testing using overrides for, 96–98
Error path testing
for boundary conditions, 31
scaling up legacy code, 215–216
software archeology and legacy code, 217
testing, 30
Errors
, in Java, 134
Event objects, coupling in, 44
Exceptions
error injection for testing, 96–98
indicating with existing no-op classes, 101–103
injecting by replacing collaborators, 99–100
thoughts on designing, 140–143
Executor
, Java packages, 173
Expiration boundary tests, 72–75
Explicit intent of development, testing implementation to match, 17
Externally triggered loop termination, encapsulation of, 94–95
Extract Class refactoring, 39–40
Extract Method refactoring, 39–40, 74, 113, 138
Facilities, testing with available, 55
Factories, 156
Factory Method and Builder, 156–159
Failure paths, testing. See Error condition verification
Fakes, 100
Feathers, Michael, 2, 25–26, 28, 145, 209
Field length limits, testing for boundary conditions in, 31
FindBugs, 7
First-time quality, and craftsmanship, 3–5, 6–10
Format string constants, exception design, 141–143
Formatted results, for exact verification of strings, 88–89
Frameworks
sometimes testing, 60
Fresh fixtures, 54
Friend
keyword
adjusting visibility with, 113–114
testing Singleton with, 126
Full stack tests
of error paths, 30
of happy path, 29
overview of, 24
Functionality
testing code at module/component level, 25
testing happy path for primary, 29
testing Singleton’s class purpose, 123–127
unit testing of value added by code, 26
Functions, locally redefining within test, 70–71
The Fundamental Theorem of Software Engineering, 32–33
Garbage-collected teardown
in common lock synchronization, 179
testing simple getters and setters, 66–67
Generated code, avoid testing of, 59–60
GetInstance()
method
in common lock synchronization, 179–180
testing Singleton’s behaviors, 122–123
Getters
constructor bootstrapping model, 65
naming conventions for, 75
verifying constructor state with, 64
GitHub, worked examples in, 193–194
Global Day of Code Retreat, 10–15
Granularity, testing, 41
Gray-box tests
testing transparency, 41
Hamcrest matchers, 67
Happy path testing
for primary purpose of code, 29
scaling up legacy code, 215–216
Hierarchical locking, 169
Hypothesis, race conditions, 171–172
IDE (Integrated development environment), software craftsmanship, 6–7
IllegalArgumentException
, Java, 134–136
Immediately invoked function expression (IIFE), 210–211
Implementation tests, scaling up legacy code, 216
Implementations
direct testing of refactored, 39–40
using factories as seams, coupling tests to, 159
using registries as seams, 155–156
verifying intent over, 52
Implicit intent of development, testing implementation to match, 17
Infinite loops, encapsulation of, 95
Infinite Monkey Theorem, 189
Initialization, and factory seams, 156–159
Injection, verification by, 77–79
Injection points, as seams, 181
Inputs, coupling test outputs to test, 48–49
Instance
, testing Singleton with constraints on, 124–125
Instance, verifying exception, 137–140
Instruction-level write-write race conditions, 168
Integrated development environment (IDE), software craftsmanship, 6–7
Intent of code
for difficult-to-test designs, 122
separating implementation from, 18–19
slipperiness of, 18
testing Singleton pattern, 120–121
verifying over implementation, 52
Intention Checker, 17
Interface-based design, 100
Interfaces
direct testing of thread task, 173
implementing callbacks through, 151
testing code using, 146
Internationalization error messages, exception design, 141
Inter-Process Communications (IPC) mechanisms, 166–167
InterruptedException
, Java, 140
Inventory, as waste in Lean manufacturing, 5
IPC (Inter-Process Communications) mechanisms, 166–167
Isolation tests, 41
Jasmine test framework
scaling up legacy code, 215–216
temporarily replacing methods in, 72
testing DOM set up using, 212
Java
adjusting visibility, 105–109, 111–112, 114–115
error condition verification, 134
exception design, 140
implementing callbacks through interfaces, 151
Singleton pattern, 120
synchronization, 179
test-driven example of. See Test-driven Java
verifying interface definition, 146
Java Concurrency in Practice, 166
JavaScript
callback functions, 151
de facto interface of, 100
declaring functions in any scope, 112
function pointers, 151
implementing callbacks, 151
write-read race condition, 167
JavaScript, legacy
retrospective, 218
software archeology, 217
on toothpaste and testing, 213–214
Java.util.concurrent
packages, Java 5, 173
JQuery Timepicker Addon project
retrospective, 218
software archeology, 217
on toothpaste and testing, 213–214
Jshint, 7
Jslint, 7
JUnit
testing simple getters and setters, 67
TestNG vs., 93
verifying exception message in, 133
verifying exception type in, 131
Law of Demeter, 46
Lean production
building quality into product, 4
preventing vs. catching defects in, 8
rework as waste in, 5
Legacy code, 209
retrospective, 218
software archeology, 217
on toothpaste and testing, 213–214
Libraries
object-oriented threading, 173–175
Line coverage, 13
Lint, 7
Localized error messages, exception design, 141–143
Logging
injecting synchronization through, 181–184
Lookup key, dependency injection in registries, 155
Loop conditions, encapsulation of, 94–96
Main()
method, testing, 196–197
Manual tests
Automated Testing Triangle, 9
test-driven Java, 200
MapReduce frameworks, 174
Mathematical functions
state verification tests of, 26–27
testing for boundary conditions in, 31–32
Mathematical view of tests, 64–66
Maturity of code, and scope of testing, 24–25
Messages, exception
design of, 141
Meszaros, Gerard, 2, 24, 37, 54, 63, 77, 100
Methodologies, Agile and Lean testing, 5–6
Methods
adjusting visibility by changing access levels, 109–111
refactoring to enhance testability, 108–109
replacing temporarily within test, 71–72
Meyers, Scott, 113
Milestones, for coverage metrics, 14–15
Minimal fixtures, 54
Minimalism, applied to software, 18
Mocks
creating test doubles, 149
danger of testing with, 201
overriding methods, 101
overview of, 100
using registries as seams, 155
integration tests at, 28
testing purpose of code at, 25
Monitoring results, reproducing race conditions, 172–173
Mutability, exception, 137
Naming conventions
for designating exposed functions as private, 210–211
getters, 75
for specific use of callbacks, 154
Nested anonymous enumerations, 70
Notifiers, as specialized callback, 154
NullPointerException
, unit testing, 12
Numerical functions, testing for boundary conditions, 31–32
Object-oriented (OO) design
as dominant design paradigm, 37–38
encapsulation and observability in, 38–42
implementation hiding in, 38
Observer pattern, 154
Operations, behavioral verification tests of, 27
OU (organizational unit), LDAP, 154
Outputs, coupling test inputs to test, 48–49
Override
encapsulation and. See Encapsulation and override
injection, 93
Package
declaration, Class:Std, 116
Packages
elevating access to code being tested, 105–107
Parallelism
deadlocks, 169
history of, 166
reproducing race conditions, 170–173
statistical verification, 187–189
synchronizing through common lock, 176–181
synchronizing through injection, 181–184
testing thread task directly, 173–175
threads, 166
Partial verification, testing for, 55
Pattern, verification of strings by, 83–85
Pattern Languages of Program Design, 101
Payload, verifying exception, 134–137
Performance tests, 41
Perl
checking stylistic problems, 7
Class::Std module, 109
function pointers, 151
package declarations, 107
verifying strings by pattern, 83–85
Perlcritic, 7
Plug-ins, avoiding testing of, 58–59
PMD
code coverage metrics, 14
static analysis tool, 7
POSIX
loading and invoking functions as callbacks, 151–152
runtime binding without error handling, 34–35
verifying error conditions, 129–130
PowerMock, 115
Preallocated exceptions, verifying exception instance, 138–139
Preemptive multitasking, 166
Principle of Least Knowledge, minimizing coupling, 46
Principles, testing. See Testing principles
Private functions, legacy JavaScript, 210–211
Private methods
adjusting visibility, 75
changing access levels, 109–110
coercing test access with reflection, 114–115
debate on testing, 40
as implementation details, 110
simplifying public interface with, 108
PRIVATE
trait, Class:Std, 116
Privateer, 115
Privileges, debugger, 190
Processes, in parallel programming, 166
Production, avoiding test code in, 51–52
Protected
method, changing access levels, 109–111
Public
method, changing access levels, 109–111
Purpose
as dimension of testing, 41
testing happy path for primary, 29
Python modules, 106
Race conditions
in common lock synchronization, 176–178, 180
deadlocks vs., 169
isolating using gdb commands, 190–191
statistical verification of, 187–189
with thread-safe components, 185–186
Random event testing, 41
Read-write race conditions, 167
Recipe, testing. See Testing recipe
Redefining variable or function, local tests, 70–71
Redundant tests, removing, 58
Refactoring
behavioral encapsulation and, 39–40
expiration boundary test with, 72–75
to provide seam for test-driven Java, 198–199
software archeology and legacy code, 217
for testable loop control, 96
testing thread task directly, 175
toothpaste, 213
References, storing in newer registries, 154–155
Reflection
testing Singleton, 126
Registration management, and factory seams, 157–159
Registries, as seams for testing, 154–156
Regression tests, 41
Regular expressions, 84–85, 88
Replace methods, temporarily within test, 71–72
Representational encapsulation, 38–39
Reproduction, race conditions, 170–173, 177–179
Resource constraints, testing for boundary conditions, 31–32
RESTRICTED
trait, Class:Std, 116
Reverse engineering, bottom-up testing, 213
Rework, as waste in Lean, 4
Risk assessment, testing third-party code, 60
Ruby, packages in, 106
Runnable
interface, Java thread task, 173–175
Run-time, testing for data permutations at, 33–35
RuntimeExceptions
, 134
Scope
scaling up for legacy code, 215–217
small tests for limiting, 55–56
testing error paths and, 30
testing granularity, 41
understanding for testing, 24–25
Seams
bringing code under test with, 145
callbacks, observers, listeners, and notifiers as, 150–154
in common lock synchronization, 176–181
complex situations rich in, 170
dependency injection as, 147–150
identifying in mess of code, 25
identifying in race conditions, 172
injection points as, 181
overview of, 145
reproducing race conditions, 172
Semantically handled edge cases, code coverage in, 12
Separating concerns, in testing, 56–57
Sequencing issues, race conditions as, 171
ServerException
, 133
ServiceFailureException
, 130–134
SetAccessible()
method, Java reflection, 115
Setters
constructor bootstrapping model, 65
dependency injection using, 147–149
Shared constants, 67–70, 85–87
Shared fixture, testing Singleton’s purpose, 124–125
Simplicity, software hygiene, 6–7
Single Responsibility Principle, 119
Singleton object, 120
Singleton pattern
as difficult-to-test design, 119–120, 122
intent, 121
removing Singleton nature, 124
testing class purpose, 123–127
testing Singleton nature, 122–123
using factories as seams, 156–158
Slash (/) character, regular expressions, 84
Smalltalk, 110
Smoke testing, 41
archeology and legacy code, 217
engineering and craftsmanship. See Engineering and craftsmanship
SOLID principles, 119
Solution, software hygiene, 6–7
Spring framework
reflection-based scheduling callbacks, 151–152
Spy feature
defined, 100
verifying value-added by function, 214
Standards, boundary conditions from, 32
conceptual framework for, 25–26
overview of, 23
state and behavioral testing, 26–27
testing alternate paths, 29–30
testing data permutations, 30–35
testing defects, 35
testing error paths, 30
testing “happy path,” 29
Static analysis tools, 7
Static checkers
disabling for test code, 48
enforcing naming convention, 49
unit testing under constraints of, 10
Statistical verification, parallelism and, 187–189
String handling
cautionary note, 90
exact verification by value, 85–87
exact verification with formatted results, 88–89
implementing callbacks through, 151–152
verification by containment, 81–83
verification by pattern, 83–85
verifying strings, 81
Stubs
defined, 100
testing with null object implementations, 101–103
Subsets of system, testing purpose of code for, 26
Supervisory control, parallelism and, 184–187
Sustainability, testing code for, 28
Swallowed exception, 140
Synchronization
injecting, 181
Syntactic marker, naming conventions, 49
System tests
based on purpose of code, 25–26
economics of, 28
Tasks, testing thread, 173–175
Taxonomy, of software hygiene, 5
Technologies, influencing testing scope, 24
Templates, and factory seams, 156–159
Test Doubles
collaborators and, 100
creating substitutes for collaborators, 77
defined, 24
Test subpackages, Java, 106
Test through the interface, 55
Test-driven development (TDD)
Java example of. See Test-driven Java
purpose of tests over time, 41
retrospective, 207
Testing
code coverage tools for, 7
craftsmanship assisted by, 8–10
inefficiencies of retesting, 5
methodologies for automated, 5–6
separate intent from implementation, 18–19, 21–22
unit test under code checker constraints, 10
avoid test code in production, 51–52
couple inputs to outputs, 48–49
overview of, 47
prefer complete over partial verification, 55
prefer minimal, fresh, transient fixtures, 54
remove code for simplicity, 58
sometimes test framework, 60
use available facilities, 55
use unique values, 57
verify intent over implementation, 52
overview of, 28
test defects, 35
test error paths, 30
test “happy path,” 29
visualization of, 29
Test-only interfaces, adjusting visibility with, 111–112
Test-then-set race conditions, 167–168
Third-party code, testing, 60
Threads
in common lock synchronization, 176–181
and deadlocks, 169
debugger APIs handling multiple, 189–191
overview of, 166
reproducing race conditions, 170–173
statistical verification, 187–189
synchronization through injection and, 181–184
testing thread task directly, 173–175
using supervisory control, 184–187
Thread-safe code, 167
Thread.State.BLOCKED
state, Java, 180
Throwable
class, verifying exception payload, 134–137
Toothpaste refactoring, 213
Toothpaste testing, 213
Top-level domains, DNS, 32
Toyota Production System, 5
Transient fixtures, tests, 54
Transparency, 41
Try/catch
, 217
Types, exception, 130–133, 141–143
UI component, JavaScript testing of, 193–194
Unified exception handling, 130
Unique values, testing with, 57
Unit testing
adjusting visibility with friend
keyword, 113–114
of alternate paths, 30
Automated Testing Triangle for, 9
under code checker constraints, 10
defined, 26
economics of, 28
granularity of, 41
of happy path, 29
objections to, 10
testing defects, 35
value-added perspective on, 25–26
URI
class, test-driven Java, 201–203
Usage of object, representational encapsulation, 38–39
Value constraints, boundary conditions in, 31–32
Value-added perspective, unit testing, 25–26
Values
exact verification of strings by, 85–87
older registries allowing storage of, 154
testing using unique, 57
verifying error conditions with return, 129–130
Variables, locally redefining test, 70–71
Verification
complete vs. partial, 55
using callbacks, 154
Verification, error condition
checking return value, 129–130
overview of, 129
Verification, string testing
cautionary note for, 90
Visibility, adjusting
changing access levels, 109–111
coerced access via reflection, 114–115
improving testability by, 75–77, 105
packaging tests with code, 105–107
Visualization, of testing recipe, 29
Waste, Lean manufacturing minimizing, 5
WebRetriever. See Test-driven Java
White-box tests
testing transparency, 41
Write-read race conditions, 167
Write-write race conditions, 168–169
XUnit Test Patterns, Meszaros, 54
Yan Framework, 147
18.219.249.210