Agile Software Design & Programming

The purpose of the Agile Programming track is to help people learn the skills, techniques and mindset needed to effectively design and develop software applications and systems with the known techniques, tools and mindset of good agile programmers.

This track is currently under development. The following shows the current state of the discussion. We will post more as specific topic areas and learning object clusters solidify.

1.1. : Test Driven Development
1.1.1. The value of test-driven developmen.
Test-driven development is often mistakenly assumed to be about writing tests for code, whereas it has much broader purpose.
The purpose of this LO is to understand and experience the value TDD provides to lower the cost of evolutionary development. The LO includes TDD's role in providing quick feedback cycles, improving the design of program interfacess, thinking about the design itself, as documentation, and for regression testing. It also includes configuring the development environment for quick turnaround (encouraging, for example, the absence of the debugger).

1.1.2. Identifying usage patterns to define the object or function interface
Writing tests before writing code gives the designer a taste for how the interface will feel in use, and provides concreteness to the proposal of its calling parameters.
The purpose of this LO is to experience the mode of creating examples of intended usage to design and grow the interface before the implementation. (This is alternatively also referred to as BDD, outside-in design, design from the client side, and example-driven-design)

1.1.3. Identifying completeness of conditions that drive usage patterns in the code
Writing tests first provides a thinking structure for determining all the conditions that will need to be included in the target behavior.
The purpose of this LO is to experience using various heuristics to identify conditions that drive detailed design of required behavior. This includes positive, negative and exception conditions, as well as having the mnemonics to remember them by (COMPLETE or BICEP as examples).

1.1.4. Avoiding duplication in the conditions
It is easy to think that having more tests is better, whereas each additional test slows the feedback cycle, grows maintenance costs, and eventually brings diminishing additional value.
The purpose of this LO is to learn to notice and avoid duplication, to reduce the number of conditions used to drive the development of the code, and to select the highest value condition from a larger set of possible conditions (for example, concentrating on the different classes of output and the input values around where the behavior is expected to change, using boundary values or all-pairs technique).

1.1.5. Red-Green-Refactor
Despite common usage, TDD is not just a matter of writing tests, but is built on a rhythm of failing test, passing test, clean code, known as "red, green, refactor".
The purpose of this LO is to get a feel for the rhythm and benefits of driving development using the red-green-refactor steps, including a feel for the benefits of shorter cycle times. To be acceptable, there would have to be some amount of lecture/theory/discussion and significant hands-on period for the student to experience the nature of the RGF cycle and the feeling of the shift to shorter and shorter cycle times.

1.1.6. Test Speed
The speed at which the tests run has a surprising impact on the designer's ability to keep the design flowing.
The purpose of this LO is to understand the importance of getting feedback quickly, strategies for keeping tests that fast, and strategies for dealing with the tests that can't be made that fast. This includes test-speedup strategies as stubbing out slow dependencies, keeping tests simple, minimizing fixture size, using faster hardware, etc.; and strategies for dealing with slow tests (that can't be made fast enough), particularly running slow tests less frequently or off the critical path. To be acceptable, there would have to be experience in improving slow tests and separating out ones that can't be sped up.

1.2. : Good Design
1.2.1. Role of Design-in-the-Large
It is a common misconception that in agile, any form of global design is bad, that all design must be immediate, small, and refactored into a macro shape.
The purpose of this LO is to understand the roles of coarse-grained design, of dealing with costly-to-change decisions, and of evolutionary architecture. This LO includes such things as choosing implementation languages, operating systems, technology frameworks; partitioning work and architecture across teams, and component-level architecture. There should be discussion around how much design is too much (identifying "the decisions we're not going to make yet") and also too little (selecting "the decisions we're better off making now"), discussion that does not imply or require a "right answer". Due to the size of the topic and the difficulty in creating meaningful labs within a class, this LO may be delivered with less detail and lighter labs. Note: in this writing, "component-level architecture" refers to the elements named when partitioning the system, those that would go into the "walking skeleton" of the system.

1.2.2. Simple design
It is natural to think that the more complicated design is the better one; however, simpler design better retain agility in the code base and therefore also in the company.
The purpose of this LO is to understand the need for and value of "simple designs" in order to avoiding over-engineering, and when faced with alternatives, to choose the simpler of them. To be acceptable, this should include several taste-tests for simple design, such as single responsibility, McCabe complexity, Beck's 4 rules of simple design, "whichever is easier-to-test", and others as they are known.

1.2.3. Evaluating Designs and Design Principles
If it is still not known how to invent good designs, quite a lot is known about how to evaluate designs.
The purpose of this LO is to practice evaluating designs, making them easier to evolve. To be acceptable, this should include practice in several of the known published principles and techniques: DRY principle, single responsibility principle, open-closed principle, Liskov substitution principle, dependency injection (inversion of control) technique, SOLID, and so on.

1.2.4. Design Patterns
Design patterns are idioms that solve common or difficult design problems.
The purpose of this LO is to learn and practice a few of the basic and well known design patterns. It is out of scope of this document to select which ones are best taught. The LO includes balancing use of design patterns with "simple design", noting that design patterns can complicate the design unnecessarily; and learning to refactor to design patterns.

1.2.5. Clean Programming
Poorly written code is hard to understand and hard to evolve, making the code base more expensive to maintain.
The purpose of this LO is to understand the value of writing easily understood code, and to learn and practice ways to do that. These include naming variables, methods, constants, functions, modules, classes, and so on; indentation, managing the sizes of methods and classes, guard clauses and conditional logic within methods, and encapsulation.

1.2.6. Listening to your tests
Problems with the automated tests are often symptoms of poor design.
The purpose of this LO is to learn test smells that hint at the need for changes to the design to improve testability. Smells include fragility in tests, indirect tests, difficulty in writing tests, and slow tests. Design changes to make include dependency injection, test doubles, headless apps, "humble" (plain-ordinary-testable) objects, design for zero-deployment testing and other ideas. This LO requires at a minimum common test smells and how to address them through design changes.

1.3. Technical Debt
1.3.1. Recognizing technical debt
The cruft that accrues in the code either from neglect or intentionally when hitting deadlines reduces code maleability: a technical debt that needs addressing.
The purpose of this LO is to understand the concept of technical debt and its mounting negative impact on productivity, and to learn how to recognize this technical debt. The LO includes understanding technical debt coming from taking short cuts, learning better ways of doing things, gaining new technical capabilities that allow you to simplify existing code; recognizing technical debt includes symptoms such as high cost in adding new functionality, high frequently of new bugs when changing code, difficulty in automating testing, and code that is difficult to understand. This LO is intended to be introductory, no lab is required.

1.3.2. Discussing technical debt choices with stakeholders
Programmers all too often complain that they have to create technical debt just because the boss says to, even despite the boss saying not to.
The purpose of this LO is to learn how to dialog with the project manager, the product owner, various other stakeholders, and the other programmers about technical debt, and to learn alternative approaches to the situation at hand. This LO is intended to be introductory, but requiring practice in discussing development tradeoffs in business language, and selecting different solutions for different situations.

1.4. Refactoring
1.4.1. Principles of refactoring
Refactoring is merely "rewriting code"; by now there are well established principles that keep the programmer moving forward and the code safe at all times.
The purpose of this LO is to develop an understanding of the principles of refactoring, namely, starting with working code, identifying code smells, taking small steps that improve the code while preserving its overall behavior, so that there is always working code. This LO is introductory, with lab work optional.

1.4.2. Code smells
The industry has worked out generally agreed upon indicators that code is in bad shape.
The purpose of this LO is to learn to assess code quality by recognizing code smells. For this LO, the minimum set of specific code smells that must be learned are long methods, comments, duplicated code, large classes, speculative generality, and nested conditionals. Others may be included.

1.4.3. Common refactorings
Some refactorings are so common and basic that every programmer should be capable of them
The purpose of this LO is to learn to perform certain common refactorings. Mandatory for all languages are: Rename (variable, constant, function/class/module), extract method/function, introduce parameter, and inline method/function. Additionally mandatory for object-oriented languages are: split class, pull up, pushdown, extract interface. This LO requires hands-on experience simplifying a codebase through several successive refactoring rounds to see the cumulative effect.

1.4.4. The larger world of refactorings
The common refactorings are not the only ones to learn, nor is it only program code that should be refactored.
The purpose of this LO is to become aware of more sophisticated refactorings, of refactorings that may be possible through specific tools, and of other domains where refactoring can be done, such as refactoring HTML and databases. This LO is introductory, with lab work optional.

1.4.5. Refactoring
Some people think that specialized refactoring tools are unnecessary, that they are nothing more than just typing faster.
The purpose of this LO is to understand the role that refactoring tools play in safely refactoring code, and the limitation of refactoring tools. This LO includes how the sequencing of refactoring can have an effect, the use of code-sniffing tools (such as PMD and others as they appear on the market), and the limitations introduced by reflection and dynamic languages. The LO requires hands-on experience using any of the refactoring tools available for the language introduced (such as IntelliJ, Eclipse, Resharper, RubyMine, and the Refactoring menu).

1.5. : Legacy code.
1.5.1. Approaching legacy code
Many programmers incorrectly think that code must be either refactored easily or thrown away and rewritten from scratch.
The purpose of this LO is to understand how to approach adding functionality to a legacy code base. It includes being able to discuss refactoring versus rewriting; the danger of adding functionality without tests; the possibility of refactoring without tests; the refactoring-first approach and the adding-tests-first approach; and running two code bases in parallel (treating one as an oracle). This LO is introductory, with labs optional.

1.5.2. Refactoring without tests
When refactoring a legacy code base, sometimes refactoring first, before adding tests, is called for.
The purpose of this LO is to give methods and experience in refactoring code when adding tests isn't yet practical. This includes strategies for making changes without tests, legacy-specific refactorings without tests, and hands-on experience in a code base that isn't designed for testability. Depending on the language selected, this lO requires:
  • In languages with refactoring tools, such as Java and C#, learning how to use the refactoring tools to make safe changes.
  • In statically typed languages, such as C++, breaking the work down into steps where the compiler will catch mistakes.
  • In dynamic languages without refactoring tools, breaking the work down into steps which are less likely to have errors.


  • 1.5.3. Retrofitting test onto legacy code
    When refactoring a legacy code base, sometimes adding tests before refactoring is called for.
    The purpose of this LO is to give methods and experience in adding tests without refactoring. This includes exposing test APIs and dependency-breaking techniques such as object seams, linker seams and preprocessor seams. Hands-on experience is required, adding tests to a code base that isn't designed for testability. Not all techniques are applicable to all languages, so the hands-on experience will be language specific.

    2.1. Acceptance Testing
    2.1.1. Types of tests to automate
    It is not enough to have just unit tests.
    The purpose of this LO is to understand the difference between unit, component and acceptance tests, what benefits they each offer, when you should use each, how they fit into an automation strategy and how they affect the choice of tools. This LO requires preparing tests for the same code at both acceptance and unit level.

    2.1.2. Tests as Specification and Documentation
    It is easy to think that the only purpose of acceptance tests is to test existing code, and to overlook their role in understanding what is to be built.
    The purpose of this LO is to experience how using acceptance tests as a specification, providing the definition of “done,” changes the way the product is built and eliminates documentation that would otherwise become outdated. To be acceptable, this would require defining "done" for several levels of abstraction (for example workflows, use cases within workflows, algorithms within workflows or use cases) and feeling confident that the definition is complete

    2.1.3. ATDD as aid to design thinking
    Acceptance tests additionally reveal information about the modularity of the system's design.
    The purpose of this LO is to experience how ATDD tests influence the modularity of the system by enabling/encouraging independent testing of components. To be acceptable, there would need to be several cycle of building ATDD tests at various appropriate levels of abstraction (for example workflow tests, algorithm tests).

    2.1.4. Tester-Business-Developer Collaboration
    Business, testing and development bring complementary viewpoints to understanding what the team is trying to build.
    The purpose of this LO is to experience how collaborating across the roles of business person, programmer and tester in writing acceptance tests helps remove ambiguity and speeds development. To be acceptable, there should be several cycles of 3-way collaboration in preparing acceptance tests that specify a sample system.

    2.1.5. ATDD Process
    Writing acceptance tests before starting to code supports the entire test-driven design sequence.
    The purpose of this LO is to experience using acceptance test to drive development and how to step into the TDD cycle.

    2.1.6. ATDD Styles & Tools
    There are multiple forms, tools and formats for expressing automated acceptance tests.
    The purpose of this LO is to gain exposure to the different ways ATDD tests can be captured, and to understand when each is appropriate. This LO requires practice expressing the same test in three different forms (and tools): a text-based form (such as cucumber), table (such as FIT), and in code (such as xUnit).

    2.1.7. Testing the system bypassing the user interface
    Too many people think that testing a system requires going through the user interface.
    The purpose of this LO is to learn strategies and techniques for automating acceptance tests without using the user interface, including the architectural support required. This LO requires using and/or defining an architecture that supports testing automated tests that bypass the UI and writing acceptance tests that exploit that support.

    2.1.8. Testing the system through the user interface
    Not being able to test bypassing the user interface does not mean that the ATDD strategies cannot be used.
    The purpose of this LO is to learn strategies and techniques for building maintainable and intent-revealing automated acceptance tests when it is not possible or practical to bypass the user interface. This LO includes using adapters or wrappers around the user interface so that good UI-agnostic acceptance tests can be used. To be acceptable, there must be experience implemented tests using a tool that allows the user to express tests in business terms and translates them into UI interactions (Robot Framework, Cucumber, or similar).

    2.1.9. Cross-functional testing
    It is a common misconception and bad habit to think that testing cross-functional attributes (also called non-functional testing) gets done only at the end of the project.
    The purpose of this LO is to understand the role of test automation in verifying cross-functional attributes, including capacity and response time, security, etc., and how to fit these into an agile process. To be acceptable, there must be experience in automating verification of at least one kind of cross-functional attribute and running the tests over subsequent iterations of growth in functionality. Note: "Cross-functional" attributes are also known as "non-functional" or "para-functional" requirements.

    2.2. : Programming the tests
    2.2.1. Coding Tests by Intention
    A common misconception is that unlike program code, test code just need to run, and are not used for communicating to others.
    The purpose of this LO is to learn how to write tests as readable as the best production code, that show to the next reader what is being verified. This LO includes making the four phases (setup, exercise, verify, cleanup) of each test obvious, expressing each phase at a suitable level of detail, and omitting anything that doesn't contribute to the specification of behavior.

    2.2.2. Testing the tests
    Just because a test passes doesn't mean it is testing anything useful.
    The purpose of this LO is to learn how to verify that the tests are, in fact, testing what you think they are. This LO includes learning the value of running the test before implementing the code, deliberately breaking the production code to verify the test, holding test inspections, and writing unit tests for test utility code. To be acceptable, there must be hands-on experience with at least 3 different ways of verifying the test code.

    2.2.3. Test execution time
    Tests that take a long time to run break the feedback rhythm or don't get run often.
    The purpose of this LO is to learn ways to keep tests fast, and strategies for dealing with the tests that can't be made fast. This LO includes build pipelines, separating slow from fast tests, replacing slow components with test doubles, using faster hardware, and so on.

    2.2.4. Fixture Setup
    It is easy to misunderstand test fixtures as trivial code.
    The purpose of this LO is to learn to write test fixtures that are clear to the reader, minimizing duplication, and that execute fast. This LO includes practice with both fresh and shared fixtures, the use of creation and finder methods, persistent and transient fixtures, and test case classes; structuring test case classes per class, per feature and per fixture, and seeing how those influence the naming of test case classes and test methods. Note: by "fixture" is meant everything that needs to be present to verify the behavior.

    2.2.5. Result Verification
    Part of creating tests is understanding how they communicate to the next programmer, help development, and stay fast.
    The purpose of this LO is to learn to express expected outcomes so they are easy to understand and minimize code duplication. This includes the use of built-in and custom assertions, guard assertions, mock objects and test spies.

    2.2.6. Use test doubles
    It is all too common a mistake to test using the real database, thinking that test doubles are hard to use and make tests fragile.
    The purpose of this LO is to learn when and how to use test doubles, including stubs, mocks, fakes and spies. To be acceptable, the student must have hands-on experience with at least stubs, mocks and fakes. Note: Here, a "stub" returns a canned answer, a "mock" is programmed with expected client behavior and fails on misbehavior, and a "fake" is a lightweight functional equivalent, used typically to go faster.

    2.2.7. Refactoring Tests
    Sometimes the tests themselves grow too awkward to read.
    The purpose of this LO is to learn when and how to refactor the tests to improve readability or performance. This includes indicators that it is time to refactor (code smells in the test code, behavior smells such as slow, interacting or unrepeatable tests, and project smells such as tests not getting run), and practice refactoring to intention-revealing code. To be acceptable, there must be hands-on experience with several of the indicators and refactoring to intention-revealing tests (as in Intention-Revealing Tests, LO #2.2.1).

    3.1. : Collaboration.
    3.1.1. Collaboration Skills
    Agile development requires programmers to communicate with each other and with others outside their specialty.
    The purpose of this LO is to get experience being good citizens in circumstances that could involve conflict, using various techniques for communicating and collaborating. These might include but are not limited to: active listening, self- or shared-facilitation, being open for suggestions & criticisms, constructive criticism, making safe-to-be-honest or safe-to-fail, giving respect, hygiene, speaking up, staying silent, debating, yielding, recognizing different communication styles. To be acceptable, the student must participate fully in a group session deciding what to build, the design or test of the product, the project plan, or setting group working conventions.

    3.1.2. Work allocation
    There are many ways to allocate work to people, from assignment to self-selection to group-defined conventions.
    The purpose of this LO is to understand different methods teams can use to divide the work among the members, the potential advantages in ownership and accountability depending on how the work is chosen. This should include assignments by a team leader, team voting on assignments, and individual selection of assignments. This LO is introductory, with lab optional.

    3.1.3. Stakeholder Conversations
    In agile development, programmers interact with stakeholders in the project to decide the best way forward.
    The purpose of this LO is to broaden the awareness of programmers to the needs of different stakeholders and those impact the design. Stakeholders to be included in this LO include sponsors, buyers, users, product owners, security, audit, compliance groups, customer support, operations, and possibly others. This LO is introductory, with lab optional.

    3.1.4. Pair Programming
    A common misconception is that pairing is two people doing one person's work.
    The purpose of this LO is experience the benefits and mechanics of pair programming. This LO includes physical setup for pair programming, ping-pong pairing and promiscuous pairing, and the social considerations around pair programming such as personal hygiene, introverts working with extraverts, and similar. To be acceptable, the student must have significant pairing time, the purpose being to learn both the benefits and difficulties involved in pair programming.

    3.1.5. Communicating design
    Many programmers think that the code communicates the design all by itself.
    The purpose of this LO is to learn how to communicate a design without using code. This includes using class diagrams, sequence diagrams, instance and deployment diagrams, CRC cards or similar. To be acceptable, the student must have described and discussed designs with other people, without resort to code.

    3.1.6. Information Radiators
    Making information visible enables collaboration.
    The purpose of this LO is learn the value of and ways to make project information visible. This LO includes typical types and formats of information radiators: task and kanban boards, story maps, burn charts, cumulative flow diagrams and similar; plus the trade-offs of physical and electronic radiators.

    3.1.7. Working spaces
    There are disadvantages to both private offices and large open workspaces.
    The purpose of this LO is understand the importance of colocation, the importance of team work spaces, and ways of setting up the work space to be effective. This LO includes such things as osmotic communication, issues of noise and privacy, team rooms, open space work areas, and similar. This LO is introductory, with labs optional.

    3.1.8. Distributed teams
    It is a misconception that agile doesn't work with distributed teams.
    The purpose of this LO is learn how to overcome the challenges inherent in distributed teams. This includes the importance building personal relationships, the role of face-to-face in building trust, the use of technology to overcome distance, the downsides of team separation, the impact of time zone and cultural differences as well as physical distance; strategies like on-site ambassadors, telephone standup meetings, code-based synchronization with frequent checkins and continuous integration, etc. This LO is introductory, with labs optional.

    3.2. : Collective accountability
    3.2.1. Collective accountability
    It is no longer the case that a programmer's work is done when the code has been written.
    The purpose of this LO is understand the concept of collective accountability and some of its implications for the organization. This includes helping other people get their work done no matter what that work is; role blurring and its implications for hiring and in job descriptions. This LO is introductory, with labs optional.

    3.2.2. Collective Ownership
    It is a common misconception that in agile, anybody can simply change anything.
    The purpose of this LO is to understand the value, implications and alternative models for collective ownership. This LO includes the three models: owner-only, any-pair, or any-one person can make a change; how to behave responsibly (for example, with respect to refactoring), the role of coding standards and tests with collective ownership. To be acceptable, the student must have hands on experience with multiple people colliding in the code base.

    3.3. : Team activities
    3.3.1. Reflection workshops
    Reflection workshops, or interim retrospectives, allow continuous improvement and can be the secret sauce to successful project outcomes.
    The purpose of this LO is to experience the value of reflection workshops. This LO includes when to hold them, how to behave, what value to expect from them; creating personal safety by treating recommendations as experiments; the implications of using a team-member versus an outside person as the facilitator. To be acceptable, there must be several interim retrospectives with recommendations implemented within a project or assignment.

    3.3.2. Daily meetings
    The daily (stand-up) meeting serves several purposes in binding the team.
    The purpose of this LO is to understand the value of a short daily meeting for the purpose of coordinating work. This includes how to behave in the meeting, how to keep them short, what to include and exclude. To be acceptable, there must be experience participating in multiple such meetings, and discussion about their effectiveness in retrospectives.

    4.1. Function-Based Development
    4.1.1. Developing in function units
    It takes practice to learn to structure work in a way that supports both fine-grained incremental development and attention to the long-term view.
    The purpose of this LO is to understand and to learn to use functionality such as user stories or equivalent as the primary work breakdown structure. This LO includes understanding the need for coarse-, medium-, and fine-grained function descriptions suited for different long-term, medium, and short-term time horizons; the fit of user stories with other function description formats such as use cases, story maps, minimum-marketable features, or feature lists; their role as tokens (as opposed to documentation of requirements) in the overall flow of development, playing a part, for example, in card-conversation-confirmation and similar usage/feedback policies; and an introduction to heuristics for good work units (for example, INVEST). To be acceptable, the student must have hands-on experience both describing functionality and using user stories or similar to drive development.

    4.1.2. Slicing
    It is still the case that most programmers do not know how to slice requests into thin small enough functionality to fit into iterations or daily code check-in.
    The purpose of this LO is to learn how to slice functionality small enough fit into iterations or daily (or more) code check-in, and to serve scheduling, reporting, and team synchronization purposes. This LO includes splitting functionality, but also splitting and handling the happy-path, business rules, UI variations, error handling, slicing by risk, and possibly others. To be acceptable, there must be hands-on experience converting larger functionality requests into ones fine-grained enough to be programmed in a single check-in session.

    4.1.3. Cross-functional constraints
    In good development practice, the cross-functional constraints are addressed early, incrementally and continuously, to avoid having negatives surprises late in the project.
    The purpose of this LO is to learn to represent and schedule development to cross-functional constraints. This LO includes expressing cross-functional constraints in some format to estimate, schedule, develop and test them. To be acceptable, the student must have hands-on experience converting larger cross-functional constraints into ones finer-grained ones. Note: "Cross-functional" constraints are also known as "non-functional" or "para-functional."

    4.1.4. Technical risk reduction
    Agile development supports good risk reduction practice, reducing the likelihood of late bad news.
    The purpose of this LO is to learn how to include technical risks into the incremental development program. This LO includes considering risks such as scaling, API compatibility, performance, use of bleeding-edge technology, and possibly others; and learning to use risk-reduction techniques such as spikes, prototypes, walking skeleton, and possibly others. To be acceptable, there must be experience identifying risks and choosing appropriate risk-reduction techniques, and hands-on experience with at least spikes and walking skeletons.

    4.2. Planning
    4.2.1. Sizing
    Good agile developers learn to size and plan quickly and effectively as part of communicating with their stakeholders.
    The purpose of this LO is to learn and practice one or more collaborative techniques for uncovering the size of the work to be done. This LO includes the importance of having the development team doing the sizing; learning one technique: blitz planning, planning poker, wideband delphi or another equivalent method; and the different sizing approaches: actual time, ideal time, story points, and t-shirt sizes.

    4.2.2. Planning at different granularities
    "Coarse-grained long term, fine-grained short term" is a planning approach that fits both the agile development team and the sponsorship team.
    The purpose of this LO is to learn and to practice predicting how much functionality can be delivered in different time periods, using different time granularities. This LO should include both longer term planning, as for releases, and shorter term planning, as for sprints and iterations.

    4.2.3. Scheduling Risk Mitigation Items
    The many forms that risk takes affect how the development team chooses to schedule work.
    The purpose of this LO is to learn to consider risks in more areas than just programming, and to learn how to participate in risk-discussion sessions. This LO includes detecting and discussing how and when to address business, social, technical, and cost/schedule risks.

    4.2.4. Sequencing work
    "Highest-business-value first" is a good initial approach to sequencing work, but not always the best.
    The purpose of this LO is to learn to sequence work across functional, cross-functional and risk aspects. This LO includes selection strategies such as easiest first, hardest first, highest business value next, highest ROI, technical risk, technical debt, minimized rework, and possibly others. To be acceptable, the student must have practice arguing for several strategies for different circumstances.

    5.1. Leveraging tools
    5.1.1. Version Control
    It is remarkable that in this day and age, many developers still do not version their code.
    The purpose of this LO is to learn the value and the two dominant models of version control, client/server and distributed. To be acceptable, there must be have hands-on experience with one and an understanding of its differences from the other.

    5.1.2. Build Tools
    Not every person on a team has to be a build magician, but everyone should at least be aware of the build tools.
    The purpose of this LO is to gain awareness the tools involved in the automated build, and how different builds suit different needs. This LO includes awareness of one or more build tools (ant, make, maven, rake, or others), plus awareness of some of the problems of and build approaches for large systems. This LO is introductory, with lab optional.

    5.1.3. Continuous Integration
    Continuous integration is more than just having a build server and running the build once a day.
    The purpose of this LO is to understand the value of and gain experience with checking in frequently to an automated build server that builds the system and runs the suite of tests against it. This LO includes understanding the benefit of reducing integration debt through frequent checkins and fewer code branches. To be acceptable, the student must have hands-on experience using a continuous integration environment.

    5.1.4. Continuous Delivery
    Feedback is not complete until the system is deployed and in use.
    The purpose of this LO is to have an awareness of the techniques that make up continuous delivery and how they address the "last mile" issues of getting working software deployed into production. These include configuration management and deploy scripts and database migration scripts. This LO is introductory, with lab optional.

    Click here to download ICAgile Learning Objectives for Agile Software Design & Programming



    Primary Authors:
    • Alistair Cockburn
    • Gerard Meszaros

    • Contributors:
    • Michael "Doc" Norton, Lean Dog
    • Ben Butler, ThoughtWorks
    • Olav Maassen, Xebia
    • Gerard Meszaros
    • Chris Turner, ThoughtWorks
    • Jeff "Cheezy" Morgan, Lean Dog
    • Venkat Subramanian, University of Houston
    • Jon Stahl, Lean Dog
    • Kevin Steffensen
    • Christian Hargraves
    • Brian Corrales
    • Jeff Nielsen, Santeon

    Contact us

    International Consortium of Agile (ICAgile)
    1000 Peachtree Industrial Blvd, #6434
    Suwanee, GA, 30024

    Stay in touch