0% found this document useful (0 votes)
44 views

Software Engineering

Software engineering involves systematically developing software through processes like requirements analysis, design, implementation, and testing. Process models outline the steps, roles, inputs, outputs, and iterations. Popular models include waterfall, rational unified process (RUP), and agile development. RUP emphasizes business modeling and requirements analysis early on. Agile focuses on frequent delivery, collaboration, and responding quickly to change. Requirements are gathered through interviews and documented as user stories, use cases, or UML diagrams. Non-functional requirements address qualities like reliability and usability. Architectures can be monolithic, component-based, client-server, or service-oriented.

Uploaded by

Eric Jiang
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views

Software Engineering

Software engineering involves systematically developing software through processes like requirements analysis, design, implementation, and testing. Process models outline the steps, roles, inputs, outputs, and iterations. Popular models include waterfall, rational unified process (RUP), and agile development. RUP emphasizes business modeling and requirements analysis early on. Agile focuses on frequent delivery, collaboration, and responding quickly to change. Requirements are gathered through interviews and documented as user stories, use cases, or UML diagrams. Non-functional requirements address qualities like reliability and usability. Architectures can be monolithic, component-based, client-server, or service-oriented.

Uploaded by

Eric Jiang
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

1

Software engineering is the systematic, disciplined, quantifiable approach to developing software.


Process Models
Generally consists of four steps
o Requirements, Design, Implementation, Testing
Relative amount of time spent on each step
The roles of individuals/organizations in each step
The input required to process into a step
The output that the step produces
Whether there is iteration between steps
Waterfall Model
o Requirements -> Design -> Implementation -> Testing
Rational Unified Process (RUP)
o Inception -> Elaboration -> Construction -> Transition
o Emphasis on Business Modelling and Requirements during Inception
o Continued emphasis on Business Modelling and Requirement in Elaboration; Increased emphasis on Analysis & Design during Elaboration
o Focus on Implementation during Construction
o Test before, during, and after Construction
o Deployment after Construction
o Unified Modeling Language
o Problems: similar to the Waterfall Model, RUPs suffer from long iterations and involve complicated requirements and design phases (UMLs take much
longer to develop than User Stories)
Android
Views are visible components in the UI
o Android passes a Canvas object to onDraw (in the view class)
onDraw is called when View is displayed
Placing the View in the Activity requires passing an instance of the view to setContentView or putting it in the XML file
When the user interacts with the View, Android invokes its onTouchEvent method (which gets passed a MotionEvent object)
Threads
o Separate (concurrent) lines of execution that allow programs to do two or more things at the same time
o Android will show an ANR error if a View does not return from handling an event within 5 seconds, or if some code running in the main thread prohibits
UI events from being handled
Any long-running code should run in a background thread (which cannot modify UI elements)
o To start a new thread, call execute() from a class that extends AsyncTask
execute() runs:
onPreExecute() in the main (UI) thread
doInBackground() in the background thread
onPostExecute() in the main (UI) thread
Multiple Activities
o When new Activities are started, Intent objects are created and passed to that Activity
The Intent object contains info about what the Activity is meant to do, as well as any data it needs to do it
When the Launcher starts an app, it looks for the Activity with the MAIN action
o To start a new Activity:
Create an Intent object with a reference to Context (this) and the Class that represents the new Activity
Add any key/value pairs to the Intents Bundle by calling putExtra
Call startActivity or startActivityForResult and pass the intent and the request code(int)
o To finish an Activity:
Create an Intent object (empty constructor)
Call putExtra with key/value pairs or putExtras with a Bundle object (where key/val pairs were set with putString)
Call setResult with the result code (usually either RESULT_OK or RESULT_CANCELED) and the Intent
Call finish()
o To return from an Activity:
onActivityResult is called in the calling Activity, with the request code, result code, and Intent object as parameters
Use request code to figure out which Activity it is thats returning (in case you created more than one)
Use Intent object to get back any return values
o Activities should be as self-contained as possible (responsible for its own persistence, instead of passing data along to the caller Activity)
Agile Software Development
Scrum, Kanban, Lean Software Development, Extreme Programming (XP)
Focuses on self-organization and motivation instead of processes and tools

Relies on frequent, small, functional releases instead of comprehensive documentation


Relies on customer collaboration instead of contract negotiation
Uses quick responses to change and constant evaluation of processes instead of a plan
Customer satisfaction is the highest priority
Changing requirements are expected
Test-driven development
Frequent delivery of software
Close cooperation between business people and developers
Progress is measured by working software
Sustainable development pace
Do the simplest thing that works
Regular reflection and adaptation
Relies on User Stories
o Simple descriptions of functionality that specify the who, what, and why of the requirement
o See Documenting Requirements
o If a task is not related to users, it is known as an engineering task
Uses Points
o Indication of effort needed to complete a user story
o Velocity number of points completed per unit time
o Important to choose a realistic velocity for each iteration (defined during each Iteration Planning Meeting)
o Do not try to make up for lost velocity
Extreme Programming (XP)

o
o Instead of Analyzing, Designing, Coding, then Testing the entire application, work on the most important features first
Software Configuration Management (SCM)
o Identification, version control, change control (tracking changes to software configuration items), auditing, reporting
o Quality control for software development
1) Share everything (use SCM repository)
Centralized location for all Software Configuration Items (SCIs), including code, documentation, requirements, tests, and project
plans
Versioning, Auditing, Dependency, Tracking (relationships between any software configuration items in that one depends on
another. For instance, a requirement may depend on another requirement being satisfied/implemented first. A piece of code may
depend on another being implemented first), Requirements Tracking (changes, ownership, completion status; PivotalTracker) ,
Security

2) Put things back where you found them (check in code regularly)
3) Flush (use continuous integration)
All code is compiled as soon as it is checked in
4) Clean up your own mess (dont break the build)
Dont check in code that doesnt compile or pass its own tests
Maintain visibility
5) Wash your hands before you eat
Use test-driven development
Write unit tests before you implement the method

Requirements
High-level requirements (business requirements) generally define why the system is being built
Low-level requirements (detailed requirements) specify how the high-level requirements will be achieved and describe what the system will do
Gathered via interviews with the customers
o Use close-ended, specific detailed questions
o Use open-ended questions to allow the customer to speak freely and explore possibilities
o Use scenarios to let the customer talk through a sequence of steps/interactions with the system
o Use probing to force the customer to think about the justification for each requirement
Requirements are hard to capture because people change their minds, needs change, stakeholders dont always reach consensus, hard to focus on what not
how, people do not always say what they mean
Documenting requirements
o Unstructured Free-form Text
Paragraphs of prose in which the customer describes what he wants
Difficult to measure progress, break the requirements into subtasks, elaborate upon details
o User Stories
Each requirement specified in a few short sentences, describing the who, what, and why of the requirement
Written from the users perspective
Who are the users? What do they know? What can they learn?
What do they want/need to do? What is their motivation?
What is the context of using the system?
What things must/should the machine do instead of the user? What will the user assume the machine will do?
Discrete, but not necessarily precise
Estimable: developers can estimate amount of work required
Traceable: know which parts of the system satisfy a requirement
Testable: know when its done
Fit into a single interation
o Use Cases
More detailed than a user story (includes how to handle error cases, preconditions/assumptions that are made before the functionality can
be allowed to proceed, postconditions/guarantees that are made after the Use Case is finished)
Describe inputs (including system state) that are required for the system to perform the task and outputs (including the change of system
state) that occur as a result of performing the task
Describe pre-conditions (Assumptions that the system makes in order to perform the task) and post-conditions (thinks that the system
makes as a result of performing the task)
Describe error handling
o Unified Modeling Language Diagrams
Important component of RUP
Diagrams explain the structure and behavior of a system
The behavioral ones are used for specifying functional requirements and describe the flow of data between objects/components, how they
should communicate, and their various state diagrams.
Designed to be unambiguous
Useful when working with off-site teams, but require a lot of up-front work to create
o Formal Specifications are math-like descriptions that are very detailed, precise, and unambiguous
Non-functional (quality) requirements and constraints
o External quality requirements describe reliability, availability, usability, efficiency/performance, security, portability
o Internal quality requirements describe testability, readability, understandability, modularity
o Constraints relate to how software should be implemented and describe the accuracy of computations, memory/bandwidth/power usage (resource
consumption management), tool/platform usage, standards, exception and user error handling
Requirements Analysis
o Good requirements are accessible (documents, organized), comprehensive/complete, understandable, unambiguous, consistent (no contradictions),
testable, traceable, measurable, correct, realistic

Software Architecture
Monolithic
o Functionality implemented by part of the system cannot be reused without using the entire system
o Tight-coupling
Component-Based
o Interface is separated from implementation and components are flexible to change
Client-Server
Software as a Service
Service Oriented Architecture
o An approach that involves creating number of services, where each service provides access to, or exposes, one or more resources via some
predetermined, agreed mechanism. Services are often, but not always, distributed on a network
o All teams expose their data and functionality through service interfaces; teams must communicate with each other through these interfaces
o All service interfaces, without exceptions, must be designed from the ground up to be externalizable; the team must plan and design to be able to
expose the interface to developers in the outside world
Model-View-Controller (MVC)
o Model data storage, integrity, consistency, queries & mutations
Corresponds to the database some form of data persistence
Can be a real database like MySQL, PostgreSQL, or an XML file, flat files
Decouple the data storage and retrieval from the other aspects such as the UI
UI does not change depending on whether the data comes from an XML file or from an Oracle DB
Central place to do all the validations such as integrity constraints and null checks
o View presentation assets and code
Corresponds to the UI
o Controller receive, interpret, and validate input; create and update views; query & modify models
Corresponds to the business logic
Lets the programmers use any language (no dependencies with the View or the Model Layers), but in practice this is not true
Design Concepts
ISO 9126 Software Quality
o Functionality
o Reliability
o Usability
o Efficiency
o Portability
o Maintainability (Internal Quality deals with code itself)
Analyzability
Readability can one look at an identifier, distinguish it from other identifiers, and understand its semantic meaning?
Understandability can one figure out the algorithm a big chunk of code is attempting to implement?
Changeability
Code is easy to change in terms of effort (time, number of lines of code affected by a potential change)
Changes do not affect other code
Stability
Is this code affected by changes elsewhere?
Testability
How easy is it to test and debug?
Reusability
o (Security)
Separation of Concerns
o A concern is a feature or behavior that is specified as part of the requirements; should be separated into smaller, more manageable pieces
Modularity
o Most common manifestation of separation of concerns, divide software into components/modules that address different pieces of requirements and
then are integrated together into a complete solution
o Components may consist of a number of classes
o Packages are collections of classes
o Leads to enhanced changeability, stability, testability, understandability (less code to read when trying to understand it)
o Anti-pattern: The Blob (not enough modularity) one component/module that contains most of the functionality/data and other that are simply
collections of field
o Anti-pattern Super-Delegator (functional decomposition, not enough modularity) main method calls a sequence of methods in other classes that
may only have one method or dont have any relation to each other, use object-oriented principles, and have names that are verbs
o Anti-pattern Poltergeist (too much modularity) classes that dont seem to do much and may not be necessary, but whose functionality affects other
classes

Functional Independence
o Each module addresses a specific subset of requirements and only exposes a simple interface to other modules
o Deals with changeability and stability
o Allows for compartmentalization when developing in a team and reuse across projects
o Cohesion level to which a module depends on itself
Do all parts of a module rely on all other parts?
o Coupling level to which a module depends on other modules
Does on module depend heavily on another?
Loose coupling when changing one module does not affect the other
Tight coupling when changing either module affects the other
o Anti-pattern Spaghetti Code Functionality goes from one component to the next, with each component relying on the other
Aspects (cross-cutting concerns)
o Some concerns go across functionality (logging, security, access to a data source)
These concerns should be separated into their own components, rather than integrated here and there into the others
o Related to changeability (if I want to change something that is used by all parts of the code, I only need to change it in one place)
o Aspect-oriented programming aspects are woven into other functions using annotations
o Anti-pattern - Cut & Paste Programming same code appears in multiple components
Abstraction and Refinement
o Abstraction focuses on what not how
o Abstraction means people can use the functionality without knowing the details
o Refinement means exposing more details (and control)
o Improves analyzability
o Procedural Abstraction refers to a sequence of instructions that a grouped together, but the name of this sequence has a meaningful name that hides
the implementation details (a methods name should explain what it does, not how it does it)
o Data abstraction collection of data that is given a name but hides the details
o Refinement/Elaboration drill down from the general to the specific, where more details are revealed the further down you go
o Control abstraction if one module depends on another, then one should be able to replace the module on which it depends with any other module
that satisfies the same interface, including any subclass
o Someone should be able to read where the method is called and know what it does, without having to go look at code to figure it out
Information Hiding
o Information in a module/component is inaccessible to other modules that have no need for it
o Modules communicate only through exposed channels/interfaces using only the information that is needed, and not all of it
o Deals with stability and changeability with testability as a tradeoff
o Private can only be used by that object (and not its subclasses)
o Protected can be used by that object or object of subclasses
o Public world-accessible
o None package-scoped
o Also includes return types dont return an entire object if only its field is needed
Object-oriented Design Principles
o Single-responsibility principle a class should only be responsible for one thing; it should have only one reason to change (cohesion)
o Open-closed principle open for extension, closed for modification; you should be able to extend it without having to change it
o Liskov Substitution principle a class should be replaceable with an instance of a subclass; a subclass must honor the semantics of the base class
o Interface segregating principle methods in an interface should be related to each other (cohesion)
o Dependency inversion principle high-level modules should not depend on low-level modules, but rather should use abstractions
Design Patterns
Five steps for going from a set of requirements to a design of classes (and their fields and methods)
o Choose the right architecture: MVC is a good place to start
o Look for data objects by using grammatical parsing
o Choose the right data structures and use class/libraries/components that already exist
o Use design patterns where appropriate
o Refactor as needed: if the design isnt right the first time, fix it until it is
Design patterns are a general, reusable solutions to commonly occurring problems; they provide descriptions or templates for how to solve a problem that can be
used in many different solutions
Creational how objects are instantiated
o Singleton
Restricts instantiation of a class to one single object. Thus, the constructor can only be called once, and there is only one instance of the class
Useful when there is an aspect and we want to ensure that there is only one instance that is shared by all other objects
Analogous to making the class static, but is preferable to making everything in the class static
o Factory Method
Separates the code that uses an object from the code that creates it

Useful when you may need to change the type of object you use, but not necessarily the way in which you use it or when you may need the
code to be flexible to use multiple types of objects in the same manner
The factory method is a (abstract) method that is used to create the object that is needed in some class, but it is up to subclass
implementations to determine the type of object to create
Dependency Injection use anonymous inner classes (useful when it comes to testing, and adds flexibility to the code)
The code that creates an object determines its dependency
Controller c = new Controller() {Reader createReader() {}};
The above code is an anonymous class that extends Controller and overrides createReader();
Single controller, many reader example (one-to-many relationship between Controller and Reader classes)
Structural how objects are composed
o Bridge
Many-to-many relationship
Maintain different independent inheritance hierarchies; bridge connects them
Many shapes, many renderers example
Implementor an abstract class or interface that defines methods for how the data is used
Concrete Implementor class that implements those methods in different manners
Abstraction an abstract class that represents the data and has an instance of the Implementor as a field which is set in the Abstractions
constructor (thus bridging the two)
Refined Abstraction provides additional detail and then uses the Implementor as needed
Client the user of the abstraction who dictates which Refined Abstraction and which Concrete Implementor to use together when it
creates objects
o Decorator
Solves the problem of needing to anticipate various combinations in advance
Beverage, ingredient example
Start off with a base class/interface (component) and extend it using a Decorator class that has a component as one of its fields. For
subclasses of the Decorator, overridden methods use the Component implementation and also add any other new functionality
Allows the possibility of extending functionality by decorating the Component at runtime, rather than doing it with custom classes at
compile-time.
Favor composition of inheritance (compose objects as you need them, rather than creating big inheritance trees in advance)
o Composite
Use when the user (client) of the object doesnt care whether there is a single object or a collection
Create an interface so that a collection is objects is treated by the client in the same way as a single object
Shopping item example
Behavioral how objects communicate
o Observer (Publish/Subscribe)
Use when you want one object to send messages to other objects, but you dont know (at compile-time) what those other objects will be,
and/or the set of objects may change during execution of the program
Generic and flexible model of connecting objects such that one is the Subject (Publisher or Observable) and is able to send messages to a
group of Observers (Subscribers or Listeners) without knowing about them at compile-time
Commonly used in UI libraries such as Java Swing and Android
Observer, logger example
o Iterator
Allows the client code to iterate over a data structure without having to know about how data is represented internally
The Iterator interface defines methods for iterating over a data structure. Each data structure then implements some interface that allows a
client to get its Iterator. The different data structure define inner classes that implement the Iterator interface.
o Strategy
Seen in the Collections API
Specify the algorithm (or strategy) to be used for a given task or context
In Java, this is a replacement for something in which youd use function pointers in C/C++ (we have a basic structure of a task, but some parts
need to be specified at the time when you run the task)
Sorting example
The structure of how you sort is independent of how you compare the elements

Analyzability
Invariants
o Something that is expected to always be true at a certain point of the program
o Program Invariant
True at arbitrary execution points; these might not be true at other points
o Class Invariant
True before and after each (public) method is called
o Preconditions
True before a method is called
o Postconditions
True after a method is called
o It is good to consider invariants before starting the implementation
o Runtime Assertion Checking
Use the assert keyword
o Soundness
How can we know the invariants are right?
o Completeness
How can we know that weve identified all the invariants?
o False Positive: an invariant may be violated even though the software is working correctly
o False Negative: all invariants may be satisfied, even though the software is not working correctly
Test Driven Development (TDD)
o Write tests before code
o Use TDD because:
Wont want to write them after the code is implemented
Tests are an executable specification: once all of them pass, you are done
Makes you think about how the code should work, particularly with error handling
o Unit Testing (JUnit)
Test individual units, which are often single methods or combinations of methods
JUnit test classes should be responsible for testing one method
JUnit test methods should be responsible for testing one input (test case)
Use meaningful names
Create new objects for each test
Readability
o The ease with which a reader can identify and differentiate tokens (variables, method names, etc.) and their syntactic meaning
o Use consistent whitespace and punctuation, unique and unambiguous identifier names, syntax (such as parentheses)
o Follow coding conventions
Understandability
o The ease with which a reader can identify the semantic meaning of the code
o What does the code do? What is its purpose?
o Meaningful and descriptive identifier names, control flow, comments, unreachable code
More on control flow
If/else statements, continue and break statements make it hard for the reader to follow code
Look at the number of decision points (places where code can branch from one path to another)
o Put the normal condition first then the unexpected condition second
o Preferable to put the positive situation first
McCabe Cyclomatic Complexity can be calculated as the number of decision points plus one
o An MCC of 10 or more is generally too complex
Generally avoid nested loops/conditionals that go more than three levels
o Follow coding conventions
Defensive Programming
How does code affect external quality?
Reliability
o The likelihood of failure-free operation what percent of the time does it do the right thing?
Availability
o The percent of time that the software is available for use
Defensive programming is meant to guard against mistakes made by yourself, other programmers who use the code, and even the libraries/APIs utilized
Generally 3 ways to deal with pre-condition failure
o Fail quietly: dont proceed and dont notify the caller
o Fail loudly: dont proceed, but notify the caller that it violated the preconditions
o Failure recovery: try to proceed anyway, even if it means producing the wrong behavior

There are 2 important differences between checking pre-conditions and checking post-conditions
o Cannot blame the caller if something goes wrong. If the assumptions are all true, then the code should guarantee something; therefore, any violation is
our fault
o Once a violation is detected, simply throwing an exception may not be enough because the state of the program may have changed, and the caller may
not be able to fix it
To deal with post-condition failure
o Attempt to roll back to a previously-known good state (of course the caller should be notified that this happened)
o If it is impractical or impossible to roll back, it may be desirable to terminate the program
o If program termination is also not an option, then a fault tolerance technique can be used to attempt to put the program in the best state possible
Exceptions are for things that should not happen
Assertions are for things that should never happen
Tradeoffs
o Improved external quality can come at a cost in terms of internal quality
o Whether the tradeoff is worth making depends on the type of program, position in the development stage, etc.
Measuring and Improving Efficiency
Code optimization is a tradeoff between
o Execution time
o Memory usage
o Code size
o Compile time
o Correctness
o Development effort/cost
o Maintainability, readability, etc.
In most cases, premature optimization is the root of all evil
Make sure that improvement in performance does not come at the cost of all other quality factors
Rules of thumb:
o Use the right data structure or algorithm
o Measure, dont guess
o Make the common case fast (80/20 rule)
o Be careful when using threads
o Dont do unnecessary things (work, memory allocation, trying to outsmart the compiler)
Important Data Structures
o Lists make guarantees about ordering and allow for duplicate values
LinkedLists and ArrayLists
Search: O(n)
Adding:
o O(1) to add to the front, O(n) to add to the tail for linked lists
o O(1) to add to the tail, O(n) if underlying array needs to be resized
Access by index: O(1) for ArrayList, O(n) for Linked List
o Sets make no guarantees about order, ensure that each value is distinct
TreeSets and HashSets
Adding and searching: O(log2n) for TreeSet, O(1) for HashSets (assuming reasonabily sized number of buckets, otherwise O(n))
Java Performance Rules of Thumb
o Avoid unnecessary work: dont call methods more than necessary
Dont use Exceptions for control flow
o Avoid unnecessary object creation
o Know the API: dont reinvent the wheel
Compiler Optimization
o No need for:
Inlining: replace simple function calls with the code itself
Dead Code Elimination: remove unreachable code
Constant folding: combine literals
Strength reduction: use simple arithmetic operations
Loop unrolling: call loop body directly if number of loops can be determined and is small
Lazy Evaluation
o Delay computation until you know you need the result
o Create an object only when you need it
Refactoring
Make the software easier to understand and modify

o Eliminate duplicate code


o Communicate its purpose without external documentation
Attempts to optimize code often causes more harm than good from an understandability standpoint <- not generally part of refactoring
Not bug fixing, although refactoring can help find bugs should not be changing the observable behavior
When to refactor:
o All the time in little bursts
o When new functionality is added
o To obtain an understanding of bugs
o Code review
Problems with refactoring:
o Relies on external entities or standards
o Interfaces: changing a public interface can be supported by changing all the callers, but changing a published interface may not be as easily resolved
o Sometimes better to rewrite from scratch
Code Smells
o Duplicated Code
Adds clutter, more points to modify functionality, more opportunities for bugs
Extract Method (for duplicated code in the same class): create a new method for lines that appear to go together, even if theyre only
invoked once
Issues include: passing parameters, side effects (what if the code changes a local variable?), naming, testing, can result in lots of
methods (okay as long as they are cohesive)
Tradeoffs: might hurt readability (can be mitigated with a good naming), might hurt performance (tradeoff between internal and
external quality)
Pull-Up Method (for duplicated code in different classes): same idea as extract method, except put the new method in a common superclass
o Long Method
Short methods are easier to understand
If comments seem necessary, separate it into well-named methods
Keep methods to a single screen (on the order of 10 lines)
Tradeoff: increased methods adds potential overhead
Look for natural places to split the method
Conditionals and loops are indications that methods can be extracted for particular cases
Use the Extract Method pattern
o Large Class
Too many instance variables (Fields) may indicate that a class is trying to do too much
Dont define local variables at the global scope; they are not fields
Probably contains a lot of duplicated code; lots of short methods is preferable to few long methods (make sure they are well named!)
Use the Extract Class pattern: create a new class and move the relevant fields and methods over
Extract Subclass or Extract Superclass: Extract Class pattern goes the composition route, whereas the inheritance route might be
preferable, especially if the subclass might only be used sometimes or if it makes sense for the superclass to be subclasses by something
else
o Primitive Obsession
Hesitancy to create small classes because they appear to be insignificant (phone numbers, ZIP codes)
Creating appropriately-named classes > appropriately-named variables
Use the Replace Data Value with Object pattern
o Message Chain
Avoid stacking calls: a.doB().doC().doD() because it means that the caller needs to know all the underlying relationships
Use the Hide Delegate pattern: create a method doD in class A so the caller doesnt have to know how it works
Testing
Goal is to find bugs, not to prove correctness
Can only prove the existence of errors and not their absence
Ask:
o Why: test objective; what do we hope to accomplish?
o How: test selection; what will we observe and how do we choose it?
o How much: test adequacy; how many observation do we have to make?
o What: which part(s) of the system do we need to test?
o When: at what point in the process do we conduct the tests?
o Where: where does the testing occur?
Types:
o Unit Test: test smallest pieces of code
o Integration Test: test combinations of units
o System Test: test full system from users perspective
o Acceptance Test: customer decides whether or not the system meets their needs

10

Validation vs. Verification:


o Was the right thing built?
o Was the thing built right?
Dynamic vs. Static analysis:
o Executing the code (in an actual environment with actual input) vs. analyzing it as text (without compiling/running it)
Failure: external behavior that is deemed to be incorrect with respect to the desired/expected behavior
Error: incorrect internal state that led to the failure
Fault: static defect in code that led to the error (a fault is also referred to as a bug)
o Manifested as a failure when it is executed and leads to an error state
o The error state must propagate to external/observable behavior
o The oracle must be able to detect that the external/observable behavior is incorrect
Test Oracles
o True Positive (TP) there is a fault; oracle says there is a failure
o True Negative (TN) there is no fault; oracle says there is no failure
o False Positive (FP) there is no fault; oracle says there is a failure
o False Negative (FN) there is a fault; oracle says there is no failure
o Completeness no false negatives
o Soundness no false positives
o Accuracy (TP + TN) / (TP + FP + TN + FN)
o Precision TP / (TP + FP)
Testability
o A piece of software is easy to test if:
Controllability it is easy to control the inputs
Observability it is easy to determine whether the outputs are correct
Sensitivity the likelihood that a fault will lead to failure for a given statement (how often a statement is executed; probability that a fault
will lead to an error state; probability that the error state will lead to failure)
o Built-in Tests
Address issues related to observability and controllability
Set/reset methods: public methods that can modify private fields and set them to any desired state, regardless of their current state
Reporter: public method that can access private fields that are otherwise not exposed
Assertions: check the state of variables at different parts of the code (not necessarily at the end)
Downside: violates encapsulation/information hiding
Testing Strategies
o Test requirements lead to measurable criteria
o A test set is expected to cover some part of the criteria
o Coverage level is the percentage of the criteria that are covered by a given test set
o Infeasibility: when some aspect of the requirement cannot be satisfied because the criteria is impossible to cover
o Options: do we generate tests given a certain desired cover level or do we generate tests, see what the coverage level is, and keep going if were not
satisfied?
o Five General Strategies:
Exhaustive Testing try all possible inputs
Random Testing randomly select inputs
Black-Box Testing select inputs based on coverage of the specification space (possible inputs/outputs)
Equivalence Partitioning
o Divide input space into Equivalence Classes which assume that similar inputs will produce similar test results
o Should test using Boundary Conditions, which are values that lie on the boundary between equivalence classes
o Single Fault Assumption:
There is only one fault in the code
For inputs a, b, c, d, if some value of a reveals the fault, then it will do so regardless of the values of b, c, or d
Weak Normal Equivalence Class
o This implies that when we have multiple inputs, we assume we dont need to test all
combinations
o Only need to cover each inputs equivalence class
o Fewest things to cover (just the individual equivalence classes)
o Fewest number of test cases to get 100% coverage
o Pairwise Normal Equivalence Class
Bugs may be caused by pairs of variables
Most things to cover (more pairs than combinations)
Fewer test cases to get 100% coverage
o Strong Normal Equivalence Class
Faults are only revealed through combinations of all variables, and not particular values of any one variable
o Robustness Testing
Must consider:

11

Values that are outside the nominal range and may be considered unexpected input
Values may not be addressed directly in the specification
Values that are likely to crash the program or cause some other unexpected behavior
o Equivalence classes determined by output domain
Use the output space in order to determine equivalence classes
Look at the domain of possible output values, break it up into equivalence classes, and then
identify equivalence classes on the input space that lead to those outputs
White-Box Testing select inputs based on coverage of the code itself (treating it as a graph)
Consider how much of the code is being executed if you havent executed code, how do you know it works?
Control Flow Graph a directed graph showing all the statements and the paths between them
Statement Coverage the percentage of statements that are executed by a test case, or collection of test cases
Branch Coverage the percentage of branches that are executed. A branch is an edge (arrow) between a decision point and the
subsequent statement
Path Coverage the percentage of paths that are executed. A path is a sequence of statements from the beginning to the end (or
to a return statement)
o Path coverage is said to subsume branch and statement coverage because 100% path coverage ensures 100%
branch/statement coverage (but not vice versa)
o Not all paths are feasible because their path conditions may not be satisfiable
o If a program contains a loop, then the number of paths may be infinite or uncountable
In this case, talk about the path conditions for specific paths or path conditions to reach a specific statement
Fault-Based Testing select inputs that indicate the absence of certain faults
Privacy
Cultural differences exist, causing legal issues such as Privacy Laws
o Censorship
o Goal is to try to understand what different groups of people want for privacy
What are developers and users perceptions of privacy?
Privacy Concerns
o Data Aggregation the system discovers additional information about the user by aggregating data over a long period of time.
o Data Distortion the system might misrepresent the data or user intent.
o Data Sharing the collected data might be given to third parties for purposes like advertising.
o Data Breaches malicious users might get access to sensitive data about other users
Reducing Privacy Concerns
o Privacy policy, license agreements describing what the system will/wont do with data
o Privacy Laws describing which national law the system is compliant with
o Anonymizing all data ensuring that none of the data has any personal identifiers
o Technical Details describing the algorithms/source code of the system in order to achieve higher trust (encryption)
o Details on Usage describe how different data are used
Qualitative Feedback Concerns
o Authorities and intelligent services
o APIs, Program correctness, viruses
o Unusable and nontransparent policies
o Lack of control
Qualitative Feedback Reducing Concerns
o Easy and fine-grained control over data
o Certification from independent trust organization
o Transparency and open source
o Trust and education
Different Types of Data
o Content of documents (eg. Email body)
o Metadata (eg. Date)
o Interaction (eg. Mouse click)
o User location (eg. City where email was sent)
o Name or personal data (eg. Email address)
o User Preferences (eg. Settings)
Privacy Framework
o Anonymization
o Data usage details
o Default encryption
o Fine-grained control over data
o Interaction data first
Do users understand their current privacy settings?

12

Can user understanding of privacy be improved using crowdsourced data?


Are there tools for configuring privacy that are preferred over the currently provided tools?
Privacy Settings
o List of all privacy settings
o Coarse grained
o Short survey
o Crowdsourced
Compare your settings to others
Mimic others
Others trusted friends, certain networks, all friends
Privacy Testing
o Code/API Bugs how can we detect if privacy settings that are in place remain the same as the software evolves and changes over time? (eg., if my
photos are currently only shared with my friends, how do I know that they wont automatically get shared with everyone due to a software bug?)
o Policy Changes how can we detect system wide policy changes that might cause privacy settings to change? (eg., if my photos are private right now,
how do we detect if there a policy change that makes all photos publicly accessible)
o Social Testing leverage ones friends on these websites to detect privacy violations
Ask a friend to see whats visible
Monitor this periodically
Notify user if something changes
Can detect over-sharing this piece of information should have been private, but it can be viewed by others
Can detect under-sharing this piece of information should have been public, but it cannot be viewed by others
Advantages:
Dont need access to source code
Can be done by an end-user
Reasons:
Added more information manually
Changed privacy settings either deliberately or accidentally
Didnt do anything there is a bug in the code or API, possibly due to code changes
Didnt do anything the social system made a wide policy change where this information for many or all of its users is now visible

You might also like