Showing posts filed under:

Development lifecycle

Salesforce B2C Solution Architecture

This diagram (provided as a Miro board) covers high-level Salesforce B2C Solution Architecture concepts, retail scenarios and C360 integrated experiences. Provided as a technical reference for architects taking the new Salesforce B2C Solution Architect certification.

Miro Board Link


Scrum at Scale

The post provides a high-level overview of the challenges to be considered when applying the Scrum delivery framework to larger scale projects. Scale in this context relates to the size of the product being delivered; one product only. Scale here does not relate to multi-product deliveries, distributed team considerations, technical complexity or user concurrency. The term product could relate to a software product, a service or indeed any tangible outcome. The Scrum framework is used worldwide in a wide variety of contexts including fighter aircraft development, farming and education in the classroom.

In essence the Scrum agile framework is founded on the idea that self-empowered, cross-functional teams delivering working product increments in business priority order produce a better outcome in a quicker timeframe than would otherwise be achievable. There’s considerably more to Scrum than this statement affords, however for brevity this context sufficiently sets the scene.

In practice many implementations dilute the value of the Scrum framework by introducing elements of traditional Waterfall style linear process; such hybrid projects are often a disaster as aligning two process model takes discipline and care, in most hybrid cases the very opposite is true. As such the real value of Scrum is achieved through adherence to the framework in its entirety; subjective preference and selective pick-and-mix type implementations are fraught with risk and equally inefficient. Scrum has key advantages over many frameworks in this respect; the principles and practices are clear, short and intuitive and therefore the learning curve is short and initial adoption straightforward.

Before moving to discuss the main topic of this post i.e. Scaling Scrum, it is worth considering the basic mechanics of the Scrum flow.

1. A Product Owner manages a product backlog of user stories prioritised by business value; the higher priority the more detailed the story may be. Lower priority stories may be very high-level and are referred to as epics.
2. A ScrumMaster supports an empowered team to deliver a set of stories within a set timeframe, i.e. sprint cycle. The definition of delivered (or done) is agreed up front but typically equates to production quality working software that satisfies user defined acceptance criteria. The ScrumMaster ensures the team is focused on a defined sprint goal and resolves obstacles.
3. During a sprint the team synchronises on a daily basis during a stand-up meeting; team members make commitments not to the ScrumMaster but to their peers.
4. After each sprint cycle a retrospective meeting is held to inspect and adapt the process.
5. On a continual basis the Product Owner inspects and adapts the user stories on the backlog – adding emerging detail.
6. One sprint leads to the next on iterative basis within the context of a release.

The main sprint artefacts are the Product Backlog (whole-product) and Sprint Backlog (agreed stories for a sprint cycle). Velocity reports are also significant in terms of understanding how accurate estimation has been and how productive the team are.

The typical Scrum team size should be in the 4-8 region a larger team can detract from effective communication and add risk to adoption of the Scrum values of Focus, Courage, Openness, Commitment and Respect; all of which work better in a small team setting. Additionally the Scrum events (ceremonies) start to become less effective the bigger the audience. This is true for any two-way collaboration; effectiveness is inversely proportionate to audience size. And so, if the optimal Scrum team size is less than 10 yet the framework is applicable to large, complex project delivery how does Scrum scale?

Scaling Scrum – Challenges

Before considering approaches to Scaling Scrum it is worthwhile first to consider some of the key challenges likely to be encountered.

1. Focus. The level of difficulty in maintaining an effective product backlog is linear to the scale of the product. Scrum requires a whole-product mindset; the bigger the product the more challenging this can become.

2. Communication. Sub-dividing a larger project across multiple Scrum teams introduces communication boundaries. Face to face communication, a key Agile principle, can be difficult to maintain. More teams typically means more time spent on synchronisation (i.e. communication), this overhead is unavoidable.

3. Interdependency. Product backlog items are seldom standalone concerns with no interdependencies. Interdependencies can be managed effectively within a single team environment, for a multi-team environment interdependencies introduce process overhead.

4. Empowerment. Perhaps a more human factor than the preceding points but important nonetheless. Multiple team environments reduce the empowerment of the single team. This can impact upon the motivation and courage of the team as consideration (respect and so on) to other teams becomes a factor. Empowerment in this context is therefore limited in a manner not encountered by a single team.

5. Scrum thinking. Scaling challenges can often result in non-Scrum practices or adaptations creeping in. This can be perception related “Is Scrum still appropriate?” or a lack of confidence in respect to how to approach the problem in the face of proven linear alternatives.

Scaling Scrum – Typical Approach

A typical approach to Scaling Scrum is to sub-divide the product backlog into themes (or features) and to introduce a Scrum team per feature, i.e. a Feature Team.

1. Focus. Ideally each Feature Team would have a dedicated Product Owner perhaps operating within a Product Owner hierarchy with a Chief Product Owner at the top. The whole-product mindset requires a single product backlog, multiple product backlogs would require cross-prioritisation and as such the approach offers no value. To ensure manageability each Product Owner will have feature specific views on the product backlog. Feature rollups will also be added to provide Product Owners at higher levels of the hierarchy with a summarised view. Also in relation to manageability epic user stories play a big part in keeping the size of the product backlog within the 100-150 region.

2. Communication. A new Scrum event is introduced; the Scrum of Scrums. In short this meeting is focused on the discussion of dependencies and related problem solving. The regularity, duration and attendees for the Scrum of Scrums is not prescribed, instead need should drive all such factors. As with many aspects of Scrum, the Scrum of Scrum meeting can be hierarchical; for example groups of teams of related features may have a Scrum of Scrum meeting, selective attendees of which may attend a higher level Scrum of Scrum meeting at the product level. Release kick-off meetings and shared team members (perhaps on a cycle) are other effective means to make cross-team communication integral to the process. On very large, or very complex projects dedicated integration teams can be introduced to ensure communication and dependency challenges are de-risked.

3. Interdependency. In addition to the communication and resolution of dependency activity occurring within the Scrum of Scrum meetings, look ahead planning is often implemented. This approach requires that a rough idea of the backlog items for the subsequent 2 sprints are tentatively identified during each sprint planning meeting. Historical average velocity can help in terms of sizing. With an indicative view of the sprint backlog well in advance dependencies can be identified and discussed well in advance.

Large Scale Scrum with LeSS

LeSS (Large-scale Scrum) is comprised of 2 scaling frameworks that extend Scrum; basic LeSS supports up to 8 teams, LeSS Huge supports scale into the thousands of participants on a single product delivery. In both cases LeSS provides an approach to scaling that is Scrum in both principle and practice.

LeSS
The LeSS framework is founded on the principle of whole-product focus; one overall Product Owner manages a single product backlog that is delivered by 2-8 teams each with a ScrumMaster. In this context, the scaled Product Owner is supported by multiple teams working directly with customers, business users and stakeholders. On larger scale products the Product Owner role will be focused more on big-picture prioritisation rather than detail clarification; supporting teams will perform the latter. LeSS Sprint cycles are aligned across all teams and whilst each team manages their own sprint backlog one and only one potentially shippable product increment is delivered. The Sprint planning event in LeSS is split into 2 defined events; Sprint Planning One (2 hours) where all teams collectively determine the backlog items for the sprint and Sprint Planning Two (2 hours) where an individual team (or multiple teams working on a common feature) define how the stories will get to done. The Sprint review event is the same in LeSS as single-team Scrum, but an additional Overall Retrospective event is added to provide 2 cycles of process inspection and adaptation; team-level and then product. The approach to communication and interdependency management is left at the discretion of the teams involved however guidance is provided in respect to observer attendance at team Daily Scrum events, multi-team meetings, Scrum of Scrum meetings and the use of Open Space and Continuous Integration techniques.

LeSS is not only a collection of principles and practices but also a process framework with a concrete set of rules (updated February 2020) to guide application.

LeSS Huge
LeSS Huge provides framework support for product deliveries beyond the 8-team limit. The LeSS Huge approach starts with categorisation of the product backlog into requirement or development areas, each with a dedicated Area Product Owner who has an area specific view onto the overall product backlog. Sub-division by requirement areas is customer-focused, sub-division by development areas focuses on the architecture of the product. In either case each individual area can be considered a scaled-up feature team which will be delivered by a (basic) LeSS implementation with up to 8 teams. With LeSS huge sprint cycles are aligned across all areas and a single product increment delivered, not one per-area. Sprint review and retrospectives are held at the area and product levels.

LeSS Huge is a significant undertaking and will have a long adoption cycle.

In conclusion the LeSS frameworks provide a structured, empirically validated extension to Scrum to support product delivery at scale. Given the increased risk LeSS implementations should be guided by expertise and experience with the LeSS principles, framework and rules. The Certified LeSS Practitioner certification and related course should be considered as part of any process risk mitigation strategy.

Scrum@Scale

Scrum@Scale is a framework for multiple Scrum Teams, authored by Jeff Sutherland, which is designed to be lightweight and based on Scrum principles and values.

Scrum@Scale contains two cycles which separate accountability for how work is done from what work is done; the ScrumMaster cycle and the Product Owner cycle. This clear separation reduces organisational conflict and provides the basis for optimal productivity and the coordination of combined effort toward a single goal.

The ScrumMaster cycle (the how) focuses on continuous improvement, impediment removal, cross-team coordination and deployment. The Scrum@Scale framework uses Scrum of Scrum (SoS) principles to organise multiple Scrum teams working together to deliver an integrated set of product increments at the end of every Sprint. A new role, the Scrum of Scrums Master is accountable for the delivery and communication aspects of the combined Sprint, an impediment backlog is introduced to prioritise impediments across coordinating teams. A Scaled Daily Scrum Event is attended by representatives from each team to ensure synchronisation on impediments, dependencies and improvements.

The Product Owner cycle (the what) focuses on strategic vision, backlog prioritisation, decomposition and refinement and release planning. The Scrum Product Owner role is expanded to a Product Owner Team which is responsible for communicating the strategic vision for the product, business alignment, prioritisation of a single product backlog and release planning. A new role, the Chief Product Owner coordinates priorities with the Product Owners that work with each Scrum team within the Scrum of Scrums.

Scrum@Scale introduces two new executive teams. The Executive Action Team serves as the organisation level ScrumMaster with overall responsibility for impediment removal and process quality and continuous improvement. The Executive MetaScrum Team fulfills the organisation level Product Owner role with overall responsibility for aligment to strategic priorities. The Executive MetaScrum Team holds a stakeholder alignment meeting every Sprint; the MetaScrum Event. This event provides an opportunity to make strategic decisions that affect the entire organisation. The Chief Product Owner presents the Product Backlog to the Executive MetaScrum Team in order to support decision making in respect to strategy, funding, resource planning and customer, market or regulatory commitments.

The ScrumMaster cycle and Product Owner cycle have two touchpoints; team level process and product/release feedback. The former simply relates to the non-scaled Scrum process where the team self-organises to improve the velocity by which product backlog items are delivered in a releasable state. The latter relates to continuous improvement in two areas; product feedback impact on the product backlog and release feedback impact on the deployment process. For both touchpoints metrics (improving velocity, quality, team happiness etc.) and transparency (absolute honesty) are key to success.

In conclusion Scrum@Scale follows a scale-free architecture where there are no artificial constraints applied and scaling can follow an organic path, based on actual requirements and time-scales. Whilst simple in concept, the practical application of Scrum@Scale will require significant commitment at all levels of the organisation.

References

Scrum Alliance
Scrum Guide
The LeSS framework
Scrum@Scale

Salesforce Package Versions

In the new world of second generation packaging (2GP) capabilities such as Unlocked Packages mean the technical aspects of packaging are no longer a concern only for ISV developers but are now equally applicable to enterprise development. The Salesforce Developer Experience (SFDX) developer guide documentation provides a great reference for those getting started with packaging which covers all the main implementation considerations. One area that isn’t covered is the management of package versions in practice; I call this a package version scheme, an example of which is included below.

Package Version Scheme:

Convention [Major.Minor.Patch.Build]

    Pre-release development; 0.1.0-x .. 0.2.9-x

  • First-release; 1.0.0-1
  • Post-initial-release bugfixes; 1.0.1-x .. 1.0.3-x
    (Patch number must increment per package version release)
  • Post-initial-release internal builds; 1.1.0-x
    (Only the Build number must increment per package version release)
    Next-release (minor enhancement); 1.1.0-x (Release with the final build number)

  • Post-minor-release bugfixes; 1.1.1-x .. 1.1.3-x
    (Patch number must increment per package version release)
  • Post-minor-release internal builds; 1.2.0-x
    (Only the Build number must increment per package version release)
    Next-release (major enhancements); 2.0.0-1

  • Post-major-release bugfixes; 2.0.1-x .. 2.0.3-x
    (Patch number must increment per release)
  • Post-major-release internal builds; 2.1.0-x
    (Only the Build number must increment per release)

Additional references:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_manpkgs_package_versions.htm
https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro.htm

Salesforce DX in Practice


Salesforce DX introduces an entirely new development paradigm for Salesforce; Source Driven development, Scratch Orgs, Unlocked packages – there’s a lot of new concepts, capabilities and tools to consider when designing a modern, collaborative development process.

This post outlines a Developer Workflow that combines the Salesforce CLI and Git version control system as one basic example of how Salesforce DX can be applied in practice. The workflow includes a reference to the type of commands that may be executed at each step, however specific details in respect to parameters etc. should be referenced at the links below.

git Reference Manual
Salesforce CLI Command Reference

Assumptions:

A Source Driven Development methodology is applied; the source of truth is git never a Salesforce org.
Source Format is always SFDX (git and local).
Scratch orgs are intended for single developer use.

Developer Workflow:

Developer1 and Developer2 will work collaboratively on a new Feature1 for ProjectA.

git: A new branch is created for ProjectA.
git: A new branch is created for Feature1.

1. Developer1 (and 2):

1.1 create a new local branch Feature1Dev1 and check out to this branch.
[code language=”bash”]$ git checkout -b Feature1Dev1[/code]

1.2 retrieve the Metadata API components from a Source org and convert to Source format. This could be by package reference or manifest.
[code language=”bash”]
$ sfdx force:mdapi:retrieve ..
$ sfdx force:mdapi:convert ..
[/code]

1.3 add source format files to the git branch (not the metadata source).
[code language=”bash”]
$ git add .
[/code]

1.4 create a Scratch org (optionally with an expiry date; max is 30 days).
[code language=”bash”]
$ sfdx force:org:create ..
[/code]

1.5 push source format to the Scratch org.
[code language=”bash”]
$ sfdx force:source:push ..
[/code]

1.6 transport data to the Scratch org.
[code language=”bash”]
$ sfdx data:soql:query ..
$ sfdx force:data:tree:export ..
$ sfdx force:data:tree:import ..
[/code]

1.7 run configuration scripts e.g. PostInstallScript (or equivalent Apex script) in the Scratch org to configure settings.
[code language=”bash”]
$ sfdx force:apex:execute ..
[/code]

1.8 open the Scratch org to make declarative changes and pull to local folder.
[code language=”bash”]
$ sfdx force:org:open ..
$ sfdx force:source:pull ..
[/code]

1.9 modify code in the VS Code IDE and push to the Scratch org. Note, SFDX tracks changes between the local folder and the Scratch org, i.e a pull command will return only detected changes.
[code language=”bash”]
$ sfdx force:source:push ..
[/code]

1.10 create a Scratch org user for any QA users involved in early system testing.
[code language=”bash”]
$ sfdx force:user:create ..
[/code]

2. Synchronisation point:

2.1 Developer1: pushes local branch Feature1Dev1 to origin.
[code language=”bash”]
$ git add .
$ git commit -m "feature1 commit.."
$ git push origin Feature1Dev1
[/code]

2.2 Developer1: create Pull Request (Feature1Dev1=>Feature1)
2.3 CI: create Scratch org, runs unit tests, runs Lightning Lint (Pull Request specific build behaviour)
2.4 Developer2: review Pull Request (Technical QA) (Feature1Dev1=>Feature1)
2.5 Developer2: merge Pull Request to Feature1 branch
2.6 CI: create Scratch org, runs unit tests, runs Lightning Lint (Commit specific build behaviour)
2.7 Developer2: fetch the Feature1 branch from origin and merge to local Feature1Dev2
[code language=”bash”]
$ git fetch origin
$ git merge origin/Feature1
[/code]

3. Feature1 is ready for testing:

3.1 Developer1: create Pull Request (Feature1=>ProjectA)
3.2 CI: create Scratch org, runs unit tests, runs Lightning Lint
3.3 Technical Lead: review Pull Request (Technical QA) (Feature1=>ProjectA)
3.4 CI: create Scratch org, runs unit tests, converts SFDX Source to Metadata API and pushes to ProjectA Salesforce org for QA (Commit specific build behaviour)

Scrum Quality Assurance

More often than not quality assurance is considered to be an implicit benefit of agile process with no specific techniques or practices applied. Integrating effective quality assurance can be one of the most challenging aspects of applying the Scrum framework.

Before considering how quality assurance factors can be applied to the Scrum framework, let’s start with a clear definition.

Quality assurance (QA) is a set of practices which collectively ensure that standards of quality are met (i.e. technical standards) and specified requirements are delivered (customer or user needs or expectations). Standards of quality may include for example measures of correctness, integrity, maintainability or usability. Quality assurance does not mean software testing; this is one element of a quality assurance process. Effective QA means there are limited defects in the first place. The core elements of a QA process include standards, audits, solution governance, testing, defect management (analysis, tracking and resolution) and communication.

Scrum Concepts

The following points describe how QA should be considered in relation to some of the core Scrum concepts.

Developer. In Scrum terms this means any project contributor such as Software Testers, UI Designers in addition to Software Developers. This term is obviously confusing and a source of misunderstanding.

Scrum Ceremonies. QA should attend all meetings (Sprint Planning, Product Backlog Grooming, Stand-ups, Reviews and Retrospectives). A team-wide, test-first philosophy is often the driving factor behind high performance Scrum teams. This concept is also referred to as acceptance-test driven development.

Working Software. This means fully tested quality software – not code complete.

Definition of Done. The DoD must include strict criteria for testing and quality.

Customer Satisfaction. Conditions of Satisfaction (or Acceptance Criteria) defined for each User Story drive the quality assurance process.

Scrum Artefacts

The following points describe how QA should be considered in relation to some of the core Scrum artefacts.

User Stories. The User Story is a concise description of a feature told from the perspective of the person who requires it. User Stories are best considered a reminder of a conversation and should be limited to the detail required for effective estimation and prioritisation.

The following (INVEST) factors should be considered in respect to the quality characteristics of a User Story;
Independent – can it be delivered in a single sprint, or do dependencies exist?
Negotiable – the user story is not a specification (reminder of a conversation)
Valuable – is there obvious intrinsic value to the user?
Estimable – can it be estimated (sufficient detail, available knowledge)?
Small – is it sized appropriately (to fit in a sprint)?
Testable – are there appropriate Conditions of Satisfaction – or Acceptance Criteria?

The Conditions of Satisfaction (CoS) are most significant to QA. Each condition is a specific, user-focused requirement for acceptance and should be written using the Given-When-Then format (or heuristic technique) as below.

Given [context] – e.g. I have created a Customer Record and Sales Invoice.
When [event] – e.g. I attempt to enter a Sales Payment above the Sales Invoice Total.
Then [outcome] – e.g. I am warned that the payment exceeds the outstanding amount.

The high-level CoS will drive the team discussion of the User Story (in a test-first approach), a “Design and Test” whiteboard approach can be useful in this respect where the team consider both the design and testing approach at the same time. Each high-level CoS will be translated into lower-level (detailed) test cases (technical; unit and integration or functional).

User Story Test Cases. The Conditions of Satisfaction (CoS) for a given User Story provide a high-level framework for the definition of specific test cases. Such test cases should be structured to address a small, focused end-to-end workflow (or scenario) to avoid interdependencies and should enable collaborative and automated testing. Effective test cases provide a simple set of step-by-step test instructions (or steps). Note, the CoS covers the happy path scenarios only, test cases must be developed also that cover critical path, alternate path, negative path, technical, validation and edge case scenarios.

Product Backlog. The Product Backlog is a single, ordered list of requirements (typically but not exclusively User Stories) used by Scrum teams. The list is constantly evolving, business value ordered and estimated by the team – including QA.

The following factors should be considered in respect to the quality characteristics of the Product Backlog;
Prioritisation – are the Product Backlog Items (PBI) accurately prioritised to a consistent scale based on business value, ROI, interdependencies and risk?
Estimation – are the PBI consistently estimated (and benchmarked) by the team?
Well Groomed – is the backlog frequently groomed by the team?

Product Backlog grooming entails User Story discussion by the whole team (lead by the Product Owner) with a view to revising and refining estimates and adding details such as new Conditions of Satisfaction. Regular sessions should be scheduled for this purpose; ideally 10% of the Sprint time should be dedicated to this task. In practice this is rarely the case, however given the direct relationship between the completeness of the CoS to the efficiency of the quality assurance process it is important that sufficient time is allowed for effective grooming.

Scrum Practices

The following points describe how QA should be considered in relation to some of the core Scrum practices.

In Sprint Testing. User Story testing must be completed within the sprint – full-stop. The Definition of Done must include this criterion. Testing a sprint behind the development is common bad practice and directly violates the working software principle; additionally this approach builds up technical debt and defect debt to be resolved at a later time. Instead, the sprint backlog must be shaped to enable collaborative design, development and testing of each user story within the sprint. High performing Scrum teams will also automate some of the tests within the sprint. The following simplistic process describes how collaborative sprint development can be applied.

Developers and Testers working collaboratively – Team Swarming:
Write the test case
Write the code
Test together (developers and testers)
Fix the bugs (developers) / Automate the test case (testers)
>> next user story

Test Automation. The ability to automate the execution of test cases (i.e. unit tests and acceptance tests) is critical at scale. In order to quickly identify cases where the current sprint development breaks the code or functionality developed in a previous sprint it is necessary to execute the related tests efficiently. Test automation also supports evaluation of the impact of changes (What-if analysis) that can help with design decisions. Further QA related benefits of test automation include the ability to apply load testing (e.g. multiple concurrent users) and performance testing types. Unlike manual testing which must be conducted in-sprint, test automation can be added outside of the sprint and be developed a separate team. High performance Scrum teams will automate critical tests within the sprint.

Test data quality has a significant impact upon the effectiveness of testing. Random data simply doesn’t work and prefabricated test data is often written to expectations and is not representative. Using production data (real data) for test purposes can violate data protection regulations and comes with the risk of inadvertent communication to the customer, supplier etc. or PII or financial information leakage. To mitigate this an approach that combines real data with obfuscation (scrambling or scrubbing) techniques can produce large scale, representative test data sets without the risk. This can take significant time to perfect however the return on this investment will be high.

Note, in addition to automated tests, a quality test plan still includes manual testing to cover exploratory testing and usability testing types. Automated tests are systematic and unable to gauge the quality of the user experience for example.

Regression Testing. The ability to run test cases developed in previous sprints (and perhaps by different teams) enables the impact of a current development to be understood immediately. This testing practice is referred to as regression testing. Regression testing effort gets bigger over time, as with User Story test cases, regression testing should occur in-sprint and automation should be used wherever possible. It is good practice to reserve time at the end of the sprint to allow the team to complete regression testing, this should also include performance and security test cases. At scale, it is often necessary to be selective in terms of which test cases to focus upon. An effective but contentious practice is to reserve the final sprint for end-to-end regression testing – this sprint is referred to as a hardening sprint; the key risk with this approach is that defect resolution from earlier sprints is deferred to this sprint. The hardening sprint should be driven from the regression test plan not the product backlog and be managed by the QA lead.

Post Release Support. Once the product is released – and despite the QA rigour applied – it is inevitable that production defects will arise. Such defects should be reviewed first by the Product Owner to determine priority and relevancy. Where defects are to be addressed immediately (show-stopper bugs etc.) the resolution work should replace similar sized work in the current sprint. In every respect the defect should be treated in the same manner as a User Story. Defects can also be placed on the Product Backlog for grooming. Where the Scrum team is providing defect resolution it is good practice to retain velocity for production defects; this proactive approach reduces the requirement to pull User Stories from the current sprint that may be in progress.

Salesforce Test Driven Development

I’ve been fortunate to have worked as a consultant Salesforce architect for the last decade, during this time I’ve encountered an interesting variety of approaches to Agile in the Salesforce space – most of which fitting with the hybrid model unfortunately – what has been noticeably absent is the application of agile engineering practices. Test Driven Development (TDD) is one of most widely understood agile engineering practices (alongside Pair Programming) – and is perhaps the most practical to adopt, however despite the benefits, despite the level of lip-service paid to the subject in practice TDD remains a rarity. With this post I hope to provide a convincing argument to Salesforce developers and architects that TDD does not add overhead to the development lifecycle and in fact the opposite is true. The Salesforce platform in development terms is maturing, the introduction of new tools and techniques such as Salesforce DX (SFDX) are testimony to this. In this context, the idea of developers working ad-hoc and in an undisciplined manner doesn’t fit, instead the consistent application of established engineering practices will play a key role moving forward. No more low quality unit tests (written as an afterthought) and no more random coding conventions and inconsistent standards. Salesforce development teams can no longer choose to hide in the void that sits between declarative development and traditional software engineering, it’s definitely time for some new habits.

This blog post draws together a high-level conceptual view of Test Driven Development with the implementation practicalities unique to the Salesforce platform.

Let’s start with great quote to set the scene.

Build it right to build the right thing“, Ron Jeffries. The concept is simple; build the product right, repeat until it’s the right product.

Test Driven Development

Test Driven Development is an XP agile engineering practice. eXtreme Programming (XP) is a software development methodology focused on customer value, continuous feedback, incremental feature delivery and team empowerment. It is a widely recognised fact that the earlier testing is applied in the software development lifecycle – the greater the value (shorter development timescales, more reliable code etc.). TDD takes this idea to its ultimate conclusion where testing occurs in front of actual coding. This may seem counterintuitive. In order to understand the impact of this fully it’s important to understand the high-level approach.

(1) Identify a low-level requirement (PBI, Task etc.)
(2) Describe the logical tests necessary to confirm that code satisfies the requirement
(3) Write the minimum code necessary to pass the tests
(4) Tidy-up the code to remove clutter, complexity and duplication

The steps above describe a design process where software evolves in very small increments with a focus on simplicity and testability. This step-by-step approach results in emergent design, where the code informs the design approach and guides the developer toward the best solution. This is the direct opposite of the traditional big-design-upfront (or BDUF) approach. The goals and benefits of TDD are many; “clean code that works” is a phrase that best summarises this (another golden Ron Jeffries quote). Note, TDD is often referred to as Test Driven Design in recognition of this emergent design side-effect.

TDD Cycle

It is imperative to understand the conceptual aspects of TDD in order to gain the full benefits, thankfully the practical application follows a relatively straightforward and approachable 3-stage cycle (Red-Green-Refactor).

Stage 1 – Red : Write the minimum code needed for a failing test. This may entail development of (or extension to) a test harness, plus the unit test code required to exercise the logical test case. The test code could be completely new or simply an augmentation to existing tests. In writing the test code the developer is forced to think through the requirement in detailed, logical terms – the type of thinking more typically applied at a later stage when writing the functional code.

It is imperative that test code evaluate predictable logical test conditions. The test code should fail for a specific, expected reason – not due to a test harness issue or due to the fact the test code itself is invalid.

Stage 2 – Green : Write the minimum amount of code needed to pass the test. The code written here must satisfy the test condition and nothing more – no embellishments.

Discipline is required to avoid the developers innate tendency to create.

Stage 3 – Refactor : The functional code should be reviewed and modified to remove clutter, complexity and duplication. Code should work (of course) but also (critically) be readable, updateable and testable.

Clean code is the objective here; if every tiny incremental addition of code satisfies the clean code criteria (readable, updateable and testable) the outcome will be a highly organised and easily maintainable code base that can be extended with new features at a consistent level of effort over time. Where such an approach is not applied it is often inevitable that a complete re-write becomes necessary once the steadily increasing incremental cost (time) of adding new features becomes intolerable.

The TDD cycle then repeats over and over until all requirements are addressed. The incremental design approach focuses upon each individual requirement one at a time. This minimalist, simple design lead approach can be difficult for experienced developers to adopt, however once the learning curve is addressed the focus on simpler designs allows easier modification, more efficient testing and faster production.

TDD in the Salesforce Context

The Salesforce (or Force.com) cloud platform is an ideal software development environment in which to adopt the Test Driven Development (TDD) agile engineering practice. The Apex programming language has integrated unit testing capabilities which reduce the level-of-effort required. Salesforce Developers are also accustomed to the idea that code requires a (platform enforced) test coverage level of 75% for production deployment. In the Salesforce development context therefore the tools are provided and concepts relating to unit test development well understood. The only challenge remaining is the mind-set shift from big-design-upfront and retrospective test code development to TDD and the agile benefits of emergent design, clean resilient code and reduced development effort.

Unit Testing on the Salesforce Platform

An Apex class can be easily annotated (@isTest) to indicate its role as a unit test class. The snippet below shows a very basic example.

[code language=”java”]
@isTest(SeeAllData=false)
private class FeatureTestClass {

@testSetup static void setup(){
// populate custom settings.
// create test data used by all tests.
}

/* **/
static testMethod void isAccountProcessed() {

// setup test specific test data and context
insert new Account(Name=’Acme Inc’);

Test.startTest();

// do something
AccountProcessor.process();

Test.stopTest();

// test outcome
System.assertEquals(1, [select count() from Account where IsProcessed__c=true]);
}
/* */
}
[/code]

The [SeeAllData=false] flag indicates that only test data created by the class is visible to the test method (plus some actual data; products, users etc.). There are circumstances where the flag must be set as [SeeAllData=true] flag, where test code is unable to create required test data due to object access permissions. The isTest annotation takes a second parameter [isParallel=true|false] which controls whether the test class can run in parallel with other tests (for expedient execution) or whether the behaviour requires serial execution (perhaps to avoid lock contention on shared resources such as custom settings).

Once a test class is implemented, adding individual tests becomes very straightforward. A standardised naming convention for the test cases can help the readability of the code; perhaps based on the expected outcome or the logical test case. Test code organisation at the class level should also be predictable and may follow a feature convention.

There are a number of methods available for the execution of test code on the Salesforce platform; Setup menu, Developer console and API (incl. IDE) as examples. Tests can also be executed asynchronously at a scheduled future time via Apex or the API (ApexTestQueueItem, ApexTestResult objects).

As the screenshot above shows the developer can configure a test execution to include all or selected test cases from multiple test classes. In the context of the TDD cycle the developer requires the ability to run just the one test case – not all, this would waste time.

Test Suites allow test classes to be grouped and executed together; this can be seen in screenshot below.

In the TDD context, where unit tests drive the development process it is important to have a clear naming convention defined for:

Test Case: expected outcome, or logical test case (readability is key)
Test Class: group of test cases relating to a given feature
Test Suite: group of test classes relating to a functional area

What is a Unit?

For the TDD cycle to be effective it can help to understand the level at which a unit test is applied. A unit is variably defined as the smallest testable part of an application, or the smallest change that still makes sense to be tested in the developer’s opinion. This of course is a subjective definition.

Common sense should be applied; a 200 line Apex trigger on Account will not be a single unit, a 20 field update on Contact also won’t be 20 units. Instead the feature being developed should be decomposed into a unit test per logical test case. This can take practice to get right, but striving to keep each test as simple as possible should be the primary guiding factor. Simple tests are easy to modify and provide a self-documenting benefit.

Advanced Unit Testing

The Apex language supports the advanced unit testing technique of Mocking which enables isolation of test execution from external factors such as API callouts or Salesforce configuration changes.

Mocking essentially involves the non-disruptive, dynamic substitution of a test specific class instance in the place of a functional class instance. Apex provides the HttpCalloutMock interface to allow test code to utilise pre-fabricated Http callout responses. The Stub API (StubProvider interface and Test.createStub method) supports the development of Mocking frameworks that enable any class to be substituted dynamically at runtime.

References

Apex Developer Guide > Testing Apex

Ron Jeffries Blog – All things XP and much more

Martin Fowler – All things Code Refactoring and much more

Salesforce DX

This post provides a practioner’s introduction to Salesforce DX (Developer Experience) a new software development lifecycle paradigm for Salesforce. Please note at the time of writing (Spring ’17 – v40.0) Salesforce DX is at public beta status.

Salesforce DX (or SFDX) – What is it?

A new set of tools and practices to accelerate the software development lifecycle on the Salesforce platform. The tools in question enable established (technology agnostic) software development models to be applied to the Salesforce context efficiently; the practices provide guidance in how to do this effectively and at scale.
Many aspects of Salesforce DX have become standard practice over the last few years; source-driven development using tools such as Jenkins and git being a good example. Other aspects such as artifact-based development, the CLI and Scratch Orgs introduce a fundamentally new paradigm.

The Salesforce development model has historically been org-centric in concept; with the entire set of metadata types representing a single monolithic code-base. This conceptual model has benefits in respect to ensuring complex interdependencies are not overlooked and code structure and conventions are considered fully in a standardised approach. In the org-centric model – and typically not exclusively – a source-code control repository is mapped at the org-level and deployments are org-based not feature or app based. Salesforce DX provides the tools and practices to change the development model from org-centric to artifact-based; where an artifact represents a collection of components (org subset) – developed, tested and deployed together in safe isolation.

SFDX Tools

CLI (Command-line Interface – sfdx)

The new SFDX CLI provides the foundation for Salesforce DX with capabilities that span authorisation, org management, metadata creation, data population, packaging and deployment. The CLI commands are extensive and clearly structured within the top-level force namespace.

command examples:

[code language=”bash”]
//CLI create a new project (specific DX folder structure plus config file)
sfdx force:project:create

//CLI needs to authorise against the DevHub (OAuth web-based flow or for CI JWT Bearer flow)
sfdx force:auth:web:login -d -a "Hub Org"

//CLI create scratch org (or set existing as default)
sfdx force:org:create -s -f config/project-scratch-def.json

//CLI push source code from local (respects the .forceignore file placed in root folder)
//Conflicts can be overwritten –forceoverwrite
//Note – Local project is the source of truth.
sfdx force:source:push

//CLI run unit tests
sfdx force:apex:test:run
[/code]

A key concept is the local project which is the primary source of truth. The project structure is different from the Metadata API folder structure with higher-level metadata types such as Object broken down into sub-folders and individual files for sub-types such as listViews and fields. This new sfdx structure (or source shape) is designed for development and source-code control system interactions whereas the longstanding Metadata API structure related to deployment primarily. Conversion between the 2 formats is necessary when creating a new sfdx project from an existing org (or simply from existing metadata) and prior to deploying a sfdx project to a Salesforce org (not Scratch Orgs). The CLI provides commands to perform the format changes as illustrated below.

[code language=”bash”]
//Create DX project > Create folder for metadata files then ..

// Retrieve unpackaged metadata
sfdx force:mdapi:retrieve -r ./mdapipkg -u <username> -k ./package.xml

// Retrieve the metadata for a package
sfdx force:mdapi:retrieve -s -r ./mdapipkg -u <username> -p <package name>

// Convert to SFDX format.
sfdx force:mdapi:convert –rootdir <retrieve folder name>

// Convert to Metadata API format.
sfdx force:source:convert -d <metadata folder name>/ –packagename package_name
[/code]

Scratch Orgs

A Scratch Org is a temporary org that can be created quickly and configured with predefined settings and preferences (Edition, languages, platform features etc.) via a JSON definition file. Scratch Orgs are easily created and deleted via the CLI; up to 50 can be created per-day (per Dev Hub) with up to 25 active concurrently, deletion occurs automatically after 7 days.

A Scratch Org is typically used for development and testing purposes and plays an enabling role in build automation. Note, unlike sandboxes, Scratch Orgs are not constrained by a refresh cycle, but also are not a clone of a source org configuration. A typical development workflow will be to create a short-lived feature branch in the Source Code Control system (SCC), create a local sfdx project (from the branch metadata) and Scratch Org, complete development and testing in the Scratch Org, commit change back to SCC and convert and deploy the change to Sandbox. In a Continuous Integration (CI) environment the CI server (Travis CI, Jenkins etc.) may initiate an automated build from the commit event. In such a scenario, headless Scratch Orgs may be used for automated testing (across editions, languages etc.).

The SFDX CLI provides commands for automating the population of data in a Scratch Org. This can be via CSV file loading or more interestingly via org-to-org copy via SOQL query export and subsequent import.

Finally, a key feature of the CLI is the automated tracking of change (the diff) between the current local project and the default Scratch Org. The CLI push and pull commands that facilitate the movement of change between the local project and the Scratch Org automatically process changed components only.

Dev Hub

The SFDX CLI must authorise to a Dev Hub before Scratch Orgs can be created; each Scratch Org is related to a parent Dev Hub. The Dev Hub is a production Salesforce org (Enterprise Edition or Unlimited Edition) – the feature can be activated from the Setup menu. A Dev Hub trial org can be created to enable safe experimentation with SFDX. Dev Hub trial orgs expire after 30 days and are limited (40 Scratch Orgs created per day, 20 active concurrently) why this is subtly different from the standard limits is unclear.

Authorisation of the Dev Hub org (and indeed any org) by the SFDX CLI is possible via OAuth Web Flow or JWT-based Flow. The latter being preferred for system authentications such as those conducted by a CI server.

For ISV (and others) working with namespaces, the Dev Hub provides a Namespace Registry capability which (as the name suggests) allows Developer Editions containing namespaces to be registered. Once the org link is complete, Scratch Orgs can be created as normal. This capability is great for ISV developing in a namespace registered org (as opposed to utilising a separate packaging org to apply the namespace).

IDE2

The new Force.com IDE2 is an Eclipse plug-in built on the SFDX CLI. Additional features of the IDE2 include the Lightning Code Analyser and Apex Code Analysis tools. The former wraps the capabilities of ESLint and the Salesforce Lightning CLI to evaluate JavaScript code against standard or custom rule sets. The latter covers syntax error detection and highlighting plus code auto-completion. The IDE2 also provides an embedded browser for editing Lightning Pages.

On initial inspection there didn’t appear to be any means to directly login/import metadata from an existing org. Presumably this must be done externally via the SFDX CLI.

Finally, the new IDE2 provides integrated tools for working with Git repositories, a key facet of the envisaged developer workflows centred around Salesforce DX.

Summary

At the time of writing, the available SFDX documentation relates primarily to the technical aspects of the tools, there is minimal information relating to process guidance (or practices). Whilst it’s relatively easy to envisage how the new tools and techniques could be integrated into development, test and deployment workflows, best-practice guidance in such areas would certainly provide confidence and accelerate adoption.

Historically, a key sticking point for source-based development (and deployment in general) in the Salesforce context has been the Metadata API coverage. In short, not all metadata types are supported and therefore automated deployments (whether Change Set or API based) are typically accompanied by pre- and post- deployment steps that manually address the gaps. As there’s no significant change in this regard, it’s likely that Scratch Orgs will require the same approach – however considering Scratch Org use cases will typically be code related this may have limited actual impact.

In general however Salesforce DX is a considerable step forward in terms of applying established software development lifecycle practices to the Salesforce context. The CLI alone is incredibly impressive and provides significant flexibility in respect to development, testing and release process. It will be interesting to see how tools vendors react to the availability of the CLI as a foundation for future, evolved IDE capabilities. Hopefully Salesforce DX represents the first step of many in this direction.

Resources

Salesforce DX Developer Guide (Beta)
Salesforce DX on Trailhead
Salesforce DX Chatter Group

Salesforce ISV Environment Strategy

salesforce-isv-environment-strategy-all

Please note – This content was previously posted on the audit9.com site directly and is re-published here as part of the consolidation of 2 blogs.

This post provides an overview of the various environments involved in delivering ISV solutions to the Salesforce AppExchange. As will be obvious to architects working outside of the ISV domain, the ISV environment strategy has some commonality to the non-ISV approach in respect to the development and testing activities but also introduces a further level of complexity and environment roles unique to the AppExchange distribution model.

Primary Org Definitions

Packaging Org

For small-scale, low complexity managed package developments the packaging and development orgs may be combined.

1. Package/Patch Upload
The Packaging Org is where the Managed Package is created and its namespace prefix defined. Package uploads in either Managed Beta or Managed Release state are initiated from this environment.

2. Patch Development Org – PDO
PDO are short-lived orgs created specifically for Patch development. Only certain components can be modified in a PDO. Once ready for distribution a Patch can be uploaded and pushed to Subscriber Orgs.

3. Push Upgrades
Uploaded Major Releases and Patches can be scheduled for push distribution to selected (or all) Subscriber Orgs. Package subscribers have no control over whether to accept pushed changes and as such it is not advisable (unless with tacit agreement) to push changes that impact the end user experience in any material way.

4. Localisation
Translation Workbench based localisation of internationalised resources.

Partner Business Org

A Partner Business Org can be provisioned upon partnership agreement with Salesforce or the same environment roles can be established within an existing production org.

1. Environment Hub
There Environment Hub enables partner orgs to be created for Development, Test and Trialforce usage. Single Sign-on can be implemented across connected orgs. A hub member org can only be connected to one hub at any given point in time. Where Trialforce is being implemented the TMO and Packaging Org must be connected to the same Environment Hub. The Environment Hub can create TSO directly, although bypassing a TMO prevents implementation of custom branding.

2. AppExchange Publishing Org – APO
This org role is for AppExchange management and is where Private and Public Listings and the Publisher Profile are stored.

3. Licence Management Org – LMO
This org role relates to the License Management App, a custom app installed by Salesforce which enables management of Packages, Package Versions, Licenses and Subscriber data resulting from AppExchange interactions. The LMO is also the entry point for Subscriber Org Login Access.

4. Channel Orders Application – COA
This org role relates to the Channel Orders app (also termed the Partner Order app), a custom app installed by Salesforce which supports automation of Service Order submissions (relating to AppExchange sales) to Salesforce.

5. Usage Metrics Reporting
Usage Metrics provides a daily update of statistics relating to Custom Object record counts (snapshot) and Visualforce Page access and performance (summaries) across all production Subscriber Orgs. There is no opt-in required for Package subscribers. The usage data is written to objects that are API accessible only; a visualisation app is available on the AppExchange to provide convenient access. Usage Metrics provide the basis for monitoring usage patterns and proactive customer retention process.

Trialforce Orgs

AppExchange listings can offer customers the ability to trial an app within a new, pre-configured Trial Org (package, data and users). This highly valuable capability is implemented with Trialforce. Trial organisations can also be created directly from Signup forms hosted on an external website or via the API. In addition to offering free trials the Trialforce solution provides a convenient option for the quick creation of pre-configured orgs for QA or demonstration purposes.

1. Trialforce Management Org – TMO
An optional environment used for centralised management of TSO for different packages. TSO can be created directly from the Environment Hub also, however such this direct approach does not support custom branding. The TMO approach does enable custom branding for Login Pages and Email Templates.

2. Trialforce Source Org – TSO
The TSO is where the package is installed (or upgraded) and configured to reflect the trial experience (user profiles, sample data etc.) A snapshot is taken of the Source org state to create a template. Note, TSO expire after a 12 month period unless a partner case is raised to request an extension. TSO are linked to the AppExchange Publishing Console manually, once a link is in place templates are listed on the Trial Templates tab.

3. Trialforce Template.
Templates listed in the Publishing Console can be submitted for Security Review. This reviews takes less time than the Package Security Review. Once approved a template can be connected to an AppExchange listing at which point the link to start a free trial appears on the AppExchange listing.

Note, each time a package is updated the TSO must be upgraded and a new template created, reviewed and connected to the AppExchange listing.

The ISVforce Guide provides further detail on the environments listed in the preceding sections.