habits • No code review and pull requests • Tripling and Mobbing as well • Remote pairing with our team in India • Slack channels for pairs comunications • Whiteboard discussions all the time
with source dependency – Underware: useful snippets, no dependencies – Domain(s): depend only on underware – Adapters: depend on domain but not on other adapters – Executables: connecting a domain with one or more adapters, almost no code
SNAPSHOT jars • Independent release of microservices • Code reuse, no frameworks • Easy to refactor, change and test • Working on insulating better Bounded Contexts
Zipkin (TraceId + SpanId) • Dedicated Monitor Events (No Log4j or similar, no log levels) • As little as possible when things work As much as possible when there is an error
consumes B api • A CDC test in A verify that A works with a B in- memory implementation • When B change, it runs all cdc tests from all modules that are B consumers
validSubmissionId: AcceptedSubmissionId @Rule @JvmField val allowRunInEnvironments = AllowRunInEnvironments @Test @RunInEnvironments(local, test, staging) fun `Releases an accepted submission in the production workflow`() { productionClient.releaseForPublication(validSubmissionId).expectSuccess() } @Test @RunInEnvironments(local, test, staging) fun `Errors for an invalid accepted submission`() { productionClient.releaseForPublication(AcceptedSubmissionId("unknown")).expectFailure() }} … interface ProductionSystem { fun releaseForPublication(id: AcceptedSubmissionId): Result<ErrorCode, Unit> }
case from a scenario • The personas in the test are Roles interfaces • Roles have an implementations which use adapters and Http/Db/Files etc. • Roles have another implementation which use only domain objects • Tests verify that the logic is correct and that there is no business logic in the adapter layer
peterProdEditor by lazy{ scenario.newProductionEditor() } val aliceTheAuthor by lazy{ scenario.newAuthor(aliceDetails, aliceId) } @WorkInProgress(until = "2019-04-15", by = "UB") @Test fun `Oasis processes a manuscript and releases it to production`() { peterProdEditor.`create a new author approval from a accepted submission`(acceptedSubmission) aliceTheAuthor.`has received an email containing the links to pdf forms to compile`(acceptedSubmission.id) peterProdEditor.`after receiving the email with a licence he can release it to production`(acceptedSubm ssion.id, LicenceType.OPEN_ACCESS) peterProdEditor.`see the submission returned on production`(acceptedSubmission.id) } } interface ProductionEditorRole { fun `after receiving the email with a licence he can release it to production`(acceptedSubmissionId… fun `see the submission returned on production`(acceptedSubmissionId: AcceptedSubmissionId) fun `create a new author approval from a accepted submission`(acceptedSubmission: AcceptedSubmission) }