kronosapiens.github.io - Mimicking DCI through Integration Tests









Search Preview

Mimicking DCI through Integration Tests

kronosapiens.github.io
DCI, or Data, Context, and Interaction, is a programming paradigm primarily developed by Trygve Reenskaug and James O. Coplien in which code is organized by ...
.io > kronosapiens.github.io

SEO audit: Content analysis

Language Error! No language localisation is found.
Title Mimicking DCI through Integration Tests
Text / HTML ratio 57 %
Frame Excellent! The website does not use iFrame solutions.
Flash Excellent! The website does not have any flash contents.
Keywords cloud behavior DCI context class test design methods tests testing unit transfer models integration objects code interaction interactions account classes
Keywords consistency
Keyword Content Title Description Headings
behavior 20
DCI 13
context 13
class 13
test 12
design 11
Headings
H1 H2 H3 H4 H5 H6
2 5 0 0 0 0
Images We found 4 images on this web page.

SEO Keywords (Single)

Keyword Occurrence Density
behavior 20 1.00 %
DCI 13 0.65 %
context 13 0.65 %
class 13 0.65 %
test 12 0.60 %
design 11 0.55 %
methods 11 0.55 %
tests 11 0.55 %
testing 10 0.50 %
unit 9 0.45 %
transfer 8 0.40 %
models 8 0.40 %
integration 8 0.40 %
objects 7 0.35 %
code 7 0.35 %
interaction 7 0.35 %
interactions 7 0.35 %
6 0.30 %
account 6 0.30 %
classes 6 0.30 %

SEO Keywords (Two Word)

Keyword Occurrence Density
of the 10 0.50 %
at the 5 0.25 %
rather than 4 0.20 %
a single 4 0.20 %
the Account 4 0.20 %
Account class 4 0.20 %
all the 4 0.20 %
unit testing 4 0.20 %
the context 4 0.20 %
at runtime 4 0.20 %
integration tests 4 0.20 %
change the 4 0.20 %
in the 4 0.20 %
DCI is 3 0.15 %
is that 3 0.15 %
of abstraction 3 0.15 %
instead of 3 0.15 %
integration test 3 0.15 %
to be 3 0.15 %
have been 3 0.15 %

SEO Keywords (Three Word)

Keyword Occurrence Density Possible Spam
the Account class 4 0.20 % No
to change the 2 0.10 % No
the benefit of 2 0.10 % No
models rather than 2 0.10 % No
flexibility at the 2 0.10 % No
to address a 2 0.10 % No
preserving the modularity 2 0.10 % No
simultaneously preserving the 2 0.10 % No
while simultaneously preserving 2 0.10 % No
in new contexts 2 0.10 % No
to reuse the 2 0.10 % No
the bank account 2 0.10 % No
interacting with each 2 0.10 % No
with each other 2 0.10 % No
benefit of DCIstyle 2 0.10 % No
all of the 2 0.10 % No
of the benefit 2 0.10 % No
of integration tests 2 0.10 % No
this test file 2 0.10 % No
the point that 2 0.10 % No

SEO Keywords (Four Word)

Keyword Occurrence Density Possible Spam
benefit of DCIstyle programming 2 0.10 % No
interacting with each other 2 0.10 % No
into the Account class 2 0.10 % No
while simultaneously preserving the 2 0.10 % No
simultaneously preserving the modularity 2 0.10 % No
is a programming paradigm 2 0.10 % No
Data Context and Interaction 2 0.10 % No
style of thinking that 2 0.10 % No
of the benefit of 2 0.10 % No
the benefit of DCIstyle 2 0.10 % No
My hope was that 1 0.05 % No
of interaction to test 1 0.05 % No
the test files would 1 0.05 % No
test the test files 1 0.05 % No
to test the test 1 0.05 % No
interaction to test the 1 0.05 % No
unit of behavior My 1 0.05 % No
ratio of interaction to 1 0.05 % No
hope was that by 1 0.05 % No
11 ratio of interaction 1 0.05 % No

Internal links in - kronosapiens.github.io

About
About
Strange Loops and Blockchains
Strange Loops and Blockchains
Trie, Merkle, Patricia: A Blockchain Story
Trie, Merkle, Patricia: A Blockchain Story
Reputation Systems: Promise and Peril
Reputation Systems: Promise and Peril
The Future of Housing, in Three Parts
The Future of Housing, in Three Parts
Proof of Work vs Proof of Stake: a Mirror of History
Proof of Work vs Proof of Stake: a Mirror of History
Introducing Talmud
Introducing Talmud
The Economics of Urban Farming
The Economics of Urban Farming
Time and Authority
Time and Authority
On Meaning in Games
On Meaning in Games
Objective Functions in Machine Learning
Objective Functions in Machine Learning
A Basic Computing Curriculum
A Basic Computing Curriculum
The Problem of Information II
The Problem of Information II
The Problem of Information
The Problem of Information
Elements of Modern Computing
Elements of Modern Computing
Blockchain as Talmud
Blockchain as Talmud
Understanding Variational Inference
Understanding Variational Inference
OpsWorks, Flask, and Chef
OpsWorks, Flask, and Chef
On Learning Some Math
On Learning Some Math
Understanding Unix Permissions
Understanding Unix Permissions
30 Feet from Michael Bloomberg
30 Feet from Michael Bloomberg
The Academy: A Machine Learning Framework
The Academy: A Machine Learning Framework
Setting up a queue service: Django, RabbitMQ, Celery on AWS
Setting up a queue service: Django, RabbitMQ, Celery on AWS
Versioning and Orthogonality in an API
Versioning and Orthogonality in an API
Designing to be Subclassed
Designing to be Subclassed
Understanding Contexts in Flask
Understanding Contexts in Flask
Setting up Unit Tests with Flask, SQLAlchemy, and Postgres
Setting up Unit Tests with Flask, SQLAlchemy, and Postgres
Understanding Package Imports in Python
Understanding Package Imports in Python
Setting up Virtual Environments in Python
Setting up Virtual Environments in Python
Creating superfunctions in Python
Creating superfunctions in Python
Some Recent Adventures
Some Recent Adventures
Sorting in pandas
Sorting in pandas
Mimicking DCI through Integration Tests
Mimicking DCI through Integration Tests
From Ruby to Python
From Ruby to Python
Self-Focus vs. Collaboration in a Programming School
Self-Focus vs. Collaboration in a Programming School
Designing Software to Influence Behavior
Designing Software to Influence Behavior
Maintaining Octopress themes as git submodules
Maintaining Octopress themes as git submodules
Setting up a test suite with FactoryGirl and Faker
Setting up a test suite with FactoryGirl and Faker
To Unit Test or not to Unit Test
To Unit Test or not to Unit Test
A Dynamic and Generally Efficient Front-End Filtering Algorithm
A Dynamic and Generally Efficient Front-End Filtering Algorithm
Trails & Ways: A Look at Rails Routing
Trails & Ways: A Look at Rails Routing
Getting Cozy with rspec_helper
Getting Cozy with rspec_helper
Exploring the ActiveRecord Metaphor
Exploring the ActiveRecord Metaphor
Civic Hacking as Inspiration
Civic Hacking as Inspiration
From Scheme to Ruby
From Scheme to Ruby
Setting up Auto-Indent in Sublime Text 2
Setting up Auto-Indent in Sublime Text 2
hello world
hello world
via RSS
Abacus

Kronosapiens.github.io Spined HTML


Mimicking DCI through Integration Tests AbacusWell-nighMimicking DCI through Integration Tests May 13, 2014 DCI, or Data, Context, and Interaction, is a programming paradigm primarily ripened by Trygve Reenskaug and James O. Coplien in which lawmaking is organized by object role in wing to stuff organized by class. Considered by some to be an incubation of the object-oriented programming paradigm, DCI strives to write a percieved shortcoming of Object-Orientation, namely, that organizing policies by matriculation (unit) does nothing to inform a developer how the lawmaking will be executed at runtime, once multiple objects have been instantiated and are busily interacting with each other. In his post on DCI, Victor Savkin provides two diagrams to illustrate this problem. Looking at these diagrams, it becomes well-spoken that while both use cases are making use of the same models, they involve completely variegated interactions. Therefore, an wringer undertaken only of the models and their methods will not help a developer understand what will unquestionably take place at runtime. The solution to this problem encapsulated by the DCI paradigm is to store context-specific policies not in models, but in specific context classes which we then inject the models into. These context classes will contain all the context-specific behavior, and will proffer and manipulate the data-containing models as necessary to get the desired result. The example that Victor gives is of a wall transfer. In the example, the worth model contains no knowledge of how to self-mastery a wall transfer – it only knows how to store and modify its balance. Victor implement the “funds transfer” interaction by created a TransferringMoney class, which accepts two worth objects, as well as a balance, extends both worth objects with context-specific methods, and then sends the necessary messages to both finance to execute the transfer. The wholesomeness of this style is that theWorthmatriculation is kept quite lightweight, with context-specific policies stuff stored in a matriculation that represents the context. This ways that it should be easy to reuse theWorthmatriculation in new contexts, extending it with context-specific methods as necessary. These diagrams (also taken from Victor’s post) illustrate the implementation of DCI, using the same four objects to implement two separate sets of interactions. Sounds great, but… DCI is not without its shortcomings. The biggest shortcoming (to my mind) is that models lose reusability. When policies is limited only to one context, then it becomes increasingly difficult to reuse that policies in new contexts. For example, if Context 3 contains methods A, B, C, and D, and we decide later on that we want to create a Context 4 that re-uses methods B and D, we’ll have to either indistinguishable the lawmaking in the new context or pericope indistinguishable lawmaking into modules to be shared wideness contexts. This would result in either a loss of DRYness or an worrying increase in complexity associated with maintaining small pieces of behavior. For example, returning to the wall worth example above, say we want to add a context where a user is withdrawing funds from an ATM. In this case, we would want to reuse the transfer_out policies from the wall transfer context, but without the transfer_in policies associated with an account-to-account transfer. One could imagine achieving this by extracting the transfer_out method into some module (TransferOuttable?) that could be included into both contexts – but at that point, why not simply write transfer_out into theWorthmatriculation and be washed-up with it? DCI seems to have been designed to increase clarity virtually contexts and interactions, at the expense of some reusability. What is there was some way to… have both? Integration tests to the rescue! DCI was created to write a perceived shortcoming in Object-Oriented diamond – namely, that information well-nigh interactions at runtime is not discernable based on information well-nigh classes and their behavior. This is the very same shortcoming that DHH and Jim Coplien have pointed out in regards to unit testing, in their wares here and here. In his critique of unit testing (which I grapple with in an older post), Jim makes the point that unit testing, while providing feedback on the policies of matriculation methods in isolation, they provide no feedback on how these classes interact at runtime. He goes on to make the point that runtime interactions are much increasingly ramified and dynamic than methods tested in isolation, and consequently unit testing can provide a false sense of security while lightweight to unquestionably test policies at a crucial level of wresting (runtime). Both James and D end up advocating for integration tests (and other tests at higher levels of abstraction) in lieu of unit tests, arguing that these tests provide increasingly relevant feedback and protection than do unit tests. What I am going to propose here is that we can use integration tests to capture the benefits of Data, Context, and Interaction diamond without the downsides of loss of reusability. In other words, to capture and document interaction as an spare layer on top of fully-featured models, rather than in lieu of them. But… how? Let’s return to the older example of the wall worth transfer. Now imagine that, instead of organizing all the transfer-specific policies into a context “class” and injecting the worth objects as dependencies, we built all the transfer policies into theWorthmatriculation (as we would do in vanilla Object Oriented design), and captured the interactions in an integration test, something like account_transfer_spec.rb. Within the individual tests, then, we could instantiate the objects and set them equal to variables representing their roles, surpassing taking them through the series of operations representing the interaction. It would squint something like the following: require 'spec_helper' describe "Account Transfer" do let(:source_account) { Account.new(balance: 100) } let(:destination_account) { Account.new(balance: 100) } describe 'transfer interactions' do it "can transfer $20" do expect(destination_account).to receive(:transfer_in).with(20) source_account.transfer_to(destination_account, 20) expect(destination_account.balance).to eq(120) expect(source_account.balance).to eq(20) end it "raises an error given insufficient funds" do expect(source_account.transfer_to(destination_account, 200)).to raise_error(RuntimeError, "Insufficient Funds") end # Any other interactions you'd like to test and document end end You’ll notice that the tests are increasingly granular than a typical integration test, with multiple assertions stuff contained within a single test. While this could be considered bad form, this is washed-up with the intention of a single test stuff meant to document a well-constructed interaction, rather than some smaller unit of behavior. My hope was that, by creating a 1:1 ratio of interaction to test, the test files would be stronger sources of documentation well-nigh high-level design. I’ll submit my thesis that this test file captures much (but not all) of the goody of DCI-style programming, in that a developer can hands read through this test file and understand how these objects are meant to be interacting with each other (given their roles), while simultaneously preserving the modularity benefits of vanilla class-based Object-Oriented design, by keeping the methods themselves inside of their classes. In addition, this style of testing brings with it all of the other benefits of integration tests, as DHH, Jim Coplien, and others have been recently discussing. Where this method fails to preserve an wholesomeness of DCI is context-level flexibility – to transpiration the context interaction, you’ll still have to unshut up the matriculation and transpiration the methods there (and then go when and transpiration the test file), rather than be worldly-wise to transpiration the methods right there in the context. It seems as though flexibility at the context level is inversely proportional to flexibility at the matriculation and overall diamond levels – it’ll be up to you to decide what works weightier for the rencontre you’re facing. Wrapping up If you’ve been pursuit the unit vs. integration test debate that’s been simmering in the Ruby polity this past month, you have probably come to fathom the relative pros and cons of various testing styles, and come to understand the importance of testing and documenting your program at various levels of abstraction. DCI is a programming paradigm designed to rectify some of the shortcomings of unit-level diamond by encouraging increasingly diamond at the interaction-level, but at the forfeit of some modularity. Wikipedia describes DCI as having the pursuit four advantages: To modernize the readability of object-oriented lawmaking by giving system policies first-class status; To cleanly separate lawmaking for rapidly waffly system policies (what the system does) from lawmaking for slowly waffly domain knowledge (what the system is), instead of combining both in one matriculation interface; To help software developers reason well-nigh system-level state and policies instead of only object state and behavior; To support an object style of thinking that is tropical to peoples’ mental models, rather than the matriculation style of thinking that overshadowed object thinking early in the history of object-oriented programming languages. Through the use of integration tests, we should be worldly-wise to capture much of the goody of DCI-style programming (aspects of 1, 3, and 4 above) by providing a single source which contains all the information (thus serving as documentation) well-nigh a single context, while simultaneously preserving the modularity of class-based OO design. In addition, integration testing goes remoter than DCI diamond vacated by providing verification of the lawfulness of the classes and methods, and proving that they work in context. The question of testing and document policies and interaction is both compelling and complex, with no single weightier answer. It will be heady to see how the thinking well-nigh testing and diamond will evolve over the upcoming months and years – helping to bring well-nigh largest software and largest experiences. Comments Please enable JavaScript to view the comments powered by Disqus. Abacus Abacus kronovet@gmail.com kronosapiens kronosapiens I'm Daniel Kronovet, a data scientist living in Tel Aviv.