If you’re using database_cleaner for your
RSpec and Capybara tests configuration for RSpec from
database_cleaner’s documentation might not work for tests flagged with js: true
work in this type of tests. However changing strategy to truncation makes all other
test run considerably slower. If you want to use truncation strategy for JS tests
and transaction in all the other use following configuration:
The DatabaseCleaner.clean_with executed before each suite will ensure the database
is clean even if some failed/bugged tests left database uncleaned.
RSpec has a tiny little matcher to test arrays which is not so easy to be found
in documentation. The matcher is: =~ (same as regex match operator). Example:
The documentation for this matcher says that this matcher checks whether actual
array contains all elements of the expected array regardless the order. Well this
isn’t fortunate description because if actual array will include expected array
together with some additional elements the test will fail:
The result is:
So the matcher in fact tests if both actual and expected arrays contain same
elements regardless the order.
This matcher doesn’t support should_not. More information can be found here.
Consider following scenario. Your domain consist of profile model
that belongs to user model, and you want to assure that once user is
being created appropriate profile is being created for this user, therefore
there are no “profile-less” users. You can easily implement such
Active Record’s callbacks:
Now you want to write profile specification that checks if profile
can be successfully saved given a user. You can implement it like
The save! method is called once, however it looks that we’ve got 2
Profile objects being saved. How could it be?
The problem is caused because let and subject in RSpec are lazily
evaluated. This is what happened. First Profile.count is evaluated
to fetch its current value (before it is changed). Next the expect
block is evaluated. In this block we call profile which build the
Profile object. While building profile user is called which
creates the user. However User model has a callback creating new
profile, here first profile is being saved. Next we call save! on just
constructed profile saving second profile instance. Now
Profile.count returns 2 instead of expected 1.
To fix the issue we need to force RSpec not to lazily evaluate
creation of user object. We can do this using let! method:
If you’re tempted to override equals() and hashCode() methods for
your entity classes don’t do it!. Simply do not override those
methods at all. Ever. It is extremely hard task to override those methods
correctly for entities, and in 99% cases default implementation -
basing on Java object’s identity - will be fine for your application. In fact I never
saw a single correct implementation of equals() and hashCode(). If
you have one please share it, so I can prove it is wrong
Lately on one of my projects I’ve encountered following implementation
God, please. Read the hashCode() contract before you start
Whenever it is invoked on the same object more than once during an
execution of a Java application, the hashCode method must
consistently return the same integer
In given implementation entity will return different hash code before
and after it has been persisted.
I won’t show equals() method implementation as it was so absurd that
it is even not worth mentioning it.
So as a summary. Rule of thumb is never override equals() or
hashCode() methods for entity classes. If you feel that you must
do it rethink if your design is correct (you’re not dealing with
separate JPA/Hibernate sessions?) or cannot the same be achieved using
Comparator or Comparable interfaces. It is better to find
workaround for those 1% cases whereas in 99% default implementation
will work just fine.
Two last days I’ve spent on the conference about Agile in
business. Conference was very interesting despite that it wasn’t
much about business. My general observation is that most discussions
about agile is missing the point. I’ve realized that after great talk
of Arie van Bennekum. His definition of Agile is:
Serving the business by being adaptive
Most of time people are fighting lightweight vs. traditional methods
of project management. Scrum or Kanban like those are the only way to do
projects in agile. The true is that those
people are totally wrong. If you’re doing Scrum, you’re doing
Scrum. If you are doing PRINCE2 it doesn’t mean that you’re not doing
it agile. You’re agile only if you are capable of delivering business
value, or achieving business goals in a adaptive way. Scrum, PRINCE2
are just a tools that properly used can help you achieving this goal.
The true is that there are no agile or non-agile methodologies by
definition. It is the people that make those methodologies agile. In
fact I’m able to prove everybody that PRINCE2 is no less agile than
Scrum or Kanban (and I’ve heard the same about PMBOK or RUP). If people
define processes and procedures that prevent them from delivering business
values and responding to changes, it is the problem of procedures not
the methodology itself.
I would say that there are no methodologies that prevent you from being
agile. You can be agile even in waterfall. Being agile doesn’t mean
doing Scrum or Kanban. In fact not always you can use those
methodologies. In some cases more formal approach is
required (or you apply some formalisms on top of Scrum or Kanban). Everything depends on certain context. If you can deliver
business value in a adaptive way you are agile no matter the
methodology or approach you use.
Lately I’ve experienced following problem while creating new rails
The problem seems to be caused by some bug in OpenSSL while it happens
on Ubuntu 12.04 and not on OSX (don’t know how about windows). If the same
happens to you change source 'https://rubygems.org' to source
'http://rubygems.org' in your Gemfile.
Simon Brown did a great talk about the
role of a software architect. Having
a bunch of architects that do the design which is further implemented
by team of developers is really not the way software should be
developed. Simon says:
Architecture should be coded, not managed.
If architect isn’t at
least interested how his architecture is being implemented, how he can
prove that his architecture is implementable at all? If at the end software
do not meet requirements, do not scale enough is it because of the bad design, or developers
improperly implemented it?
Unfortunately it is very common that developers are treated as
brainless machines that just type code. Those who gains certain level of
experience became software architects, and since then create diagrams
and designs which is implemented by less experienced
(and less paid) developers. The problem with this model is that such
architects do not evaluate if their design actually works. If it doesn’t work
they blame developers (those idiots cannot implemented thing that was
given and fully documented in the design). They also miss the feedback
from the developers.
Software architect should be a role in a project rather just a
position in the company. Architect should be a part of a team and
shouldn’t be responsible only for design. He should be
responsible for proper implementation of a design together with other
team members which plays other roles in a project. It doesn’t mean
that architects must code though they should be able and at least
should be interested how their architecture is being implemented. Close
collaboration with team members that play architect and other roles
is a must in order to guarantee the implementability of an architecture. It
also supports principle of ubiquitous language.
Collaboration also guarantees quick feedback about the
correctness of an architecture and sharing knowledge and experience
across all team members (so after a while we have a whole team of architects).