To be fair I need some fresh air, but at the same time I’m pretty tired having to look for a new project.
First things first, I started by updating my CV, my website, doing some housekeeping on my github repos and starting to post some new things to make some advertising.
As usual I’ve started by reviewing the typical web sites and applying for those job offers I believe could be interesting, sending emails to the agencies I’ve worked for before and telling my friends and colleagues that I am ‘open to new opportunities’.
But then the worse part of all this situation comes in. I started receiving every day up to five emails from agencies. Most of them didn’t even take five minutes to read my profile or the email I sent them, which I took my time to write hoping it would help on filtering what I was going to receive, but no, that was not the case.
Of those that matched my profile, casually or by reading it, many of them are urgent and almost all have these things in common:
Some of them contained very different font types between paragraphs, which clearly means a copy and paste from a previous email or document. Even a couple of them were for a different person or at least my name was not in the email but another one’s was. Also most of them were looking for permanent positions, and that’s something I’d like to avoid if possible, I love to work as freelance.
They all looked like a factory with no interest in the quality of the product or the offer.
With a few good exceptions which I keep in my records, the rest are not of my interest or at least aren’t what I need to have the future I want to have.
At this point I realised that something was going really bad. That was not the way and there should be better, different way to find the next project.
After some enquiries, a friend of mine told me about Toptal App engineer community. He told me that it’s a company that does it differently.
I took some time to make my investigations and they seem to be the answer. The first thing they do different is the kind of questions they ask to start applying. No silly and unrelated questions, no filling questions with no sense, just the right questions. That form is destined to be the starting point for an interview, not to opt to a position but to opt to be part of the team, the pool of engineers.
That seems to be a new way of doing things and ensuring only the best engineers are part of it.
I don’t know how this new adventure is going to end, but I promise you to write a following post telling you what happened and what the experience has been for me.
]]>In this case we had a greenfield project in front of us, as nothing done regarding automation was usable here. Obviously my advice was to opt for a Calabash based solution as I believe it’s a great, ‘standardised’ and long term solution.
Calabash is a cucumber based solution that works pretty well with iOS. Of corse you find some problems, the main one is that is an intrusive solution based on the inclusion of an http server. That server allows the communication between the cucumber Gem and the iOS app, to access to the UI elements and perform the different actions on it. That brings the problem of being dependent on the system.
With Swift calabash still works, but with the new UI Testing framework a new solution appears.
Up to now I didn’t dive into the nitty-gritties of the tool and to do it, there is no better way than creating an app.
It’s going to be a simple app that will only allow you to make some voice records on your iPhone, I could call it YAMVR, but probably I will go for something more glamourous.
So stay tunned and send any comment you have if you want me to check something special or add any feature to the app.
Thanks for reading me and don’t forget to follow me on twitter and check my repos in github.
]]>My first approach was to change those behavior that didn’t fit in my needs. And the result was … nothing. It’s like that doesn’t apply to it if you are using a global setting. You can find many solutions thought the internet telling you to user setTintColor on the MFMailComposeViewController object you’ve just created, and they will work if you don’t use the appearance proxy at some point of your app initialization like:
1 2 3 4 |
|
If you did it, forget about using:
1 2 3 4 |
|
The result is going to be the same nothing I had.
But the good new is that there is a solution. I know it’s not the most elegant one but it works and you can save a lot of time investigating that I already invested. The solution is to change the global setting in the appearance proxy to match what you need and set it back to the original behavior when the dialog is dismissed.
As you know there is not going to be any dialog with navigation bar while the mail composer is present, it is safe to change it. To revert the changes, you need to do it in - (void)mailComposeController:(MFMailComposeViewController)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError)error. I use a singleton to contain the configuration colors I need to restore the original look&feel, if you don’t have it, you need to implement a mechanism to do it or you’ll have a coupled and dependent code.
Thanks for reading and don’t forget to share and follow me in twitter @guillemfg.
]]>The firs one is how to include code that behaves differently when it’s running on iOS 7 than when it’s running on iOS 8, for example. I’ve found two main different ways to do it.
Most of the times, the problem comes because of a change in the signature of an API or the deprecation of the methods. In this case the easiest way is to check if the object responds to the given selector. Two examples are NSOperation and UIApplication.
1 2 3 4 5 6 7 8 |
|
1 2 3 4 5 6 7 8 |
|
The second option is using NSFundationVersionNumber. This option gives you the flexibility to behave differently not because of any restriction, but because functional requirements or just because you like it.
1 2 3 4 5 6 7 |
|
You can use the defined constants:
Also OS X has its own ones.
]]>In this post is where we really start doing BDD, so get ready to enter to the new and exciting world of cucumber and behaviour driven development.
In previous post I’ve introduced the concept of cucumber, and in this post we are going to start with it. But first I’d like to give you a brief introduction about cucumber and what is it.
Cucumber is an set of tools that allows us to write tests in “natural language” that are readable by the computer and tell it what to test and how to test. Notice that I’ve written “natural language” between quotes and in italics. That is because we should make a couple precissions here. First, the language is natural because it can be read as a natural language written story, but is not so natural in the sense that we can’t write it as it comes, but we have to follow some conventions that describe the gherkin syntax. Second, the test, as said before, are not going to work out of the box. Eventhough there are some steps that work with no additional effort, most of the steps will need a definition from your side.
You could say - “what’s the point in writting the tests if we have to do another development job behind?”
Well, the advantage you get from this is the ability to have clearer tests that can be mantained with lot less effort and that can be written, read and maintained by third party and non technical people.
A good definition of what is gerkhin is in The Cucumber Book: Behaviour-Driven Development for Testes and Developers, an excellent book that I highly recomend you to read if you want to be a “Cucumber Master”.
“Gherkin gives us a lightweight structure for documenting examples of the behavior our stakeholders want, in a way that it can be easily understood both by the stakeholders and by Cucumber.”
Let’s see an example:
1 2 3 4 5 6 7 8 |
|
You can see this peace of code is written in a way anyone could understand, well, anyone who speaks english. What about a non english speaker stake holder? Well, gherkin syntax can be written in 40 different languages. You can see a list of available languages by running cucumber gem as ‘cucumber –i18n help’ and you’ll be listed all available languages. At this moment, this is what my system shows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
|
So we could write the same peace of code we wrote before as.
1 2 3 4 5 6 7 8 |
|
And cucumber should be able to proceed the same way as when it was written in english. Of course the steps definitions won’t be called the same or will do any translation, but we can map them.
Gherkin is basically a set of keywords organised in a certain way and followed by sentences that might or might not contain parameters and have to be defined as steps.
The keywords used by gherkin are:
First level keywords are used to separate different tests and group them, while the second level ones are to define each step or provide data to test on. I won’t go deeper on this as it is not the purpose of this port serie. As I commented before, if you really want to get more information go and buy the book The Cucumber Book: Behaviour-Driven Development for Testes and Developers, it’s at the high level Pragmatic Programmers always offer.
It all looks very nice, but, does it work? And how does that work?
Well, let’s start by writting our first feature.
If you remember a previous post in this series called BDD - Mastermind : Internal Design, I defined there the acceptance criterias the way a stakeholder would define them ( more or less, that’s my humble contribution ). Let’s bring it back to write a couple of them in gherkin.
As you can imagine there are many ways to write those acceptance criterias in gherkin. The one I choosed is the following one.
1 2 3 |
|
As you might deduct, the step “Given I am on the Initial Screen” includes
There are, at least, two ways we can do it. Creating one step for each condition and then putting them all together in a single step called “Given I am on the Initial Screen” or creating all steps into the “Given I am on the Initial Screen”.
I decided to go this second way, but it would be a good practice if you try to do it the other way and see how it works the same way or even better.
So let’s dive into the definition of the steps.
First of all, go to your project folder, be sure you are in the same folder as your .xcproject and then run
1 2 3 4 |
|
When it is finished, open the new created .xcworkspace file and build the new target you have ending in -cal . You need to do it because cucumber needs a binary to run the tests on, otherwise you are going to start having complains from cucumber.
In the project folder you’ll see a new folder called features, that’s where all cucumber magic lives.
When you open the .feature file and replace the default feature for your new feature and you run cucumber, this is what you are going to see:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Note that the command used to run the test ‘DEVICE_TARGET=’iPhone 6 (8.1 Simulator)’ cucumber‘. Please take a look at calabash documentation for more options.
You can see how cucumber helps us.
You can implement step definitions for undefined steps with these snippets:
Given(/^I am on the Initial Screen$/) do pending # express the regexp above with the code you wish you had end
Then(/^a new game should be ready$/) do pending # express the regexp above with the code you wish you had end
Those are the steps you need to implement inside your features/step_definitions/mastermind_steps.rb file. Let’s take a look on how I’ve defined them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
To match one buy one the acceptance criterias with the steps let’s split it.
1 2 3 |
|
Previoulsy to this step, you can find a new class in the code called MMCombinationRow that has been created with TDD and ensures containing five cells, one result cell and four color cells. So what’s missing here is the number of rows.
Another way to implement this check is:
1 2 3 |
|
Go and implement the rest and see how it fails and what have you got to change to make it pass and then go and run the unit tests to ensure you didn’t break anything.
If all goes fine, just making a git checkout of Step 7 and you should see something like this:
Remember you can find the code of this post in this commit, Step 8.
If you like it, please share! Thank you for reading me.
]]>In the previous post I went through a way to test the visible result of the custom view in a very intuitive way. It was just an exercise to test how, in a simple way, we could have a complete test of how we expect our view looks like. The truth is that this is a feeble method as it depends on an image that might or might not be 100% achievable by the tools we can make use of.
The purpose of the previous post was to introduce the technique we are going to use in this post. We are going to go through a technique that allows us to test the final behavior in a more secure and maintainable way.
You can find the code corresponding to this post in this commit. Go and get it!
The second element we have on the screen is the results cell. If you remember from the first post of the series, we defined three areas to consider. Area number three is a special kind of view that provides different visual aspects depending on the result we are providing. The rules are described in the second post of the series BDD - Mastermind : Internal design, but we need add a few more “conditions” to have a really robust view that does what we want it to do.
First - We are only accepting two different symbols, no matter which symbols but just two different.
Second - If the first symbol is a space, then it is considered there are no symbols of the first type and all the symbols are considered second kind.
Third - As there is no specification, the circles will try to fill as much space as possible. One symbol will end in a single big circle.
With this in mind we have enough information to start creating the tests to implement the result cell.
A very common practice is to create helper methods to simplify the test and provide more clarity. In this case we need to create a combination generator, so I implement this random combination generators.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
Now that we have all we need, let’s write some tests. I won’t go though each test as they are trivial, just list them.
As I commented before, testing against images has some important limitations like depending on the device implementation, small changes makes the test fail, etc … So, which is the best way to do it? Well nothing better than comparing a view with another view. That way we can be sure there is no difference and we can update easily the implementation.
To do it, you just need to create a view that looks like what you expect your view to look like.
You might think, that is duplicating the effort.
Well, create a dummy view that just does one thing is not duplicating the effort, is prototyping what you expect to obtain and also lets you define some rules that you might translate to your view.
Let’s take a look at the dummy view I’ve implemented and you’ll understand better what I mean.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
|
This is the final implementation of the view, but usually it will grow with your development. Adding new features that you expect to find in your view. And more important, will protect you from changing what you expect to see if you make any change in your code in the future.
With that in mind, the tests become a lot more clear.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Take a look at the rest of the test, I think they are pretty clear, but if you believe there is something you can’t see, just send me an email or leave me a comment.
And with this post I finish with the TDD by now and we can start with the BDD.
Please, leave me comments, share and like if you can! See you in the next post.
]]>If you thought we were going to jump straight to BDD I’m afraid you’ll have to wait a little more. To understand it, first of all I’m going to explain which is the framework I decided to use to BDD and how does it work. With all that info you’ll understand why we need to prepare the things to be able to BDD.
You can find the code corresponding to this post in this commit. Go and get it!
If you go to calabash web site you’ll find this definition.
Calabash enables you to write and execute automated acceptance tests of mobile apps. Calabash is cross-platform, supporting Android and iOS native apps. It is open source and free, and has a company, Xamarin, backing and developing it.
The reasons I decided to go with calabash after some investigation and research are diverse. First of all was the ease of integrating it in your projects. Opposite to other platforms it is just a question of a few sentences to be able to integrate it. Second, it works with cucumber. I really love cucumber as a way to interface with non technical people and be able to understand the same things and write acceptance criterias that we both understand and agree, and more important, we can convert them in tests.
When you are done with this post, never before ;), you can go to github calabash iOS repository and read how to install the gem and integrate it in your projects so you are able to follow the steps of this series of posts while you build your own, secure and testable app.
What’s more important to understand in this post is that calabash works with the accessibility labels to inspect and perform tasks on the simulator and the device. That’s the reason why we can’t go straight to the tests when we are going to create an app that contains a bunch of custom views and we need to see if that view is red, blue, green or yellow for example. Sadly this is something we can’t get out of the box by now. But the good news are that we can create a view that is testable in that way.
First thing we need to do is to convert what is a view perception into an accessible label. How are we going to do it? Keep reading and you’ll know how.
As usual we’ll start by creating a test file to test what I decided to call MMCell.
The strategy used to create a view that behaves as we want it to behave visually when we can’t test that it really happens is to break it in to parts. One is tested with TDD and ensures that when setting properties on a view the visual changes happens as we expect. The other part is that those visual changes are expressed in a simple way in the accessibility label.
To do it we’ll use two properties.
To better understand how we are going to make it, let’s take a look at the first test:
1 2 3 4 5 6 7 8 9 10 |
|
The test is very simple. We get a random height and a random width, both between 0 and 200, and check that when we set the frame of the view the path generated matches what we expect. This doesn’t guarantees that this is what is going to be drawn. To do it we need to go one step forward.
1 2 3 4 5 6 7 8 9 10 |
|
This test what basically does is to check if, when drawRect is called also fill is called on bezierPath object. To do it I use one of the best friends you can have when TDDing, Mocks. Sadly this is something that is not natively implemented in XCTest, so we need to find third party developments to use it. There are different libraries that implement mocks for iOS. In this case I decided to choose OCMock which is a very well known and tested libraries, but OCMockito is also an excellent option.
Basically a mock is an object that “replaces” totally or partially the object you are trying to test or an object you want to behave in a certain way so you check what happens or make things happen in a controlled environment.
I know this sounds a little weird, so if you want me to write a full post about Mocking in iOS, please ask me for it in the comments or twitter and I’ll prepare it.
This is a good moment to introduce another player that will join you projects very often.
If you are already familiar with CocoaPods you can jump straight to Testing what it looks like.
In CocoaPods Web Site they define themselves as
CocoaPods is the dependency manager for Objective-C projects. It has thousands of libraries and can help you scale your projects elegantly.
I would add to it that they do it in an awesome and very clean way.
Until I discovered CocoaPods I needed to include, organize and maintain third party developments manually. CocoaPods let’s you do it all in a very clean and isolated way so you can start using the those libraries in less than five minutes.
Let’s see how to do it in our case.
You have a very complete instruction set in CocoaPods Web Site but basically is three steps.
After those three simple steps you’ll have a new .xcworkspace file with two projects in it, one your project and the other the project to build the pods library.
From this point you just need to include the pod header you need in each file you need it. In this case by now I just need to include <OCMock/OCMock.h> in the Test File.
The content of this first version of the Podfile is the following.
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
xcodeproj 'MasterMind'
target :MasterMindTests do
pod 'OCMock', '~> 3.1.1'
end
Note that I added the pod only to the Test target, that means this pod won’t be available in release target, which is what we want.
We need to do the same we’ve done with bezierPath with color so we ensure that “setFill” is called on color property when “drawRect” is called on the view.
This test will make it.
1 2 3 4 5 6 7 8 9 10 |
|
At this point we know the properties are set, updated on changes, called SetNeedsDiplay to request redraw ( look at the code ) and we are sure that they are called when drawRect is called, but how can we ensure the last result is what we expect to be. There are many ways to do it so here is what I suggest in this case. Remember I’m not trying to be exhaustive in this series but create an exercise to show you all the possibilities we have so far to test an app.
The best way to let the test see if the final result is what we want is compare it with an image that represents what we want, so that’s what we are going to do. In this case I took some images that represents what the view should look like in different circumstances. Those are:
Now, how to check the view against the image? This is the test.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
The base is that we obtain the NSData representation of both images and we compare them, that will tell us if they match or doesn’t.
And that’s all for now. Now we have testable view cells. We need testable result cells and then we can start with BDD.
Remember you can find the code of this post in this commit.
If you like it, please share! If you believe there is some part that needs more detail or want to suggest a new post like with Mocking, just send me your thoughts.
Thank you for reading me.
In the next post BDD - Mastermind : View Preparation we’ll find a more robust and maintainable way to create tests for the visual aspect.
]]>It’s time to get your hands dirty. To make it really easy I’ve decided to tag each relevant commit with step numbers so you can follow step by step the process. I recommend you to code your own version, but if at some point you are lost, just checkout the step where you got lost and we’ll be synchronized again.
First thing to do is create your project and have it ready to run. You can create a new project or checkout this commit or just checkout from terminal by :
1 2 3 |
|
As you might now the process of TDD is basically writing a test, seeing how it fails, implement the solution and run again the test until it passes. I’m not going to go deep in what is TDD as there are many webs that explain very well how to do TDD like Quality Coding specially the screencast series starting with Intro to Objectve-C TDD.
So, assuming you know what is TDD and how to do it, let’s start our process.
What I do is take each requirement and try to dissect it in all the possible unitary tests I can do covering all possibilities. So let’s start on the first one.
The first test to write is to be sure that right from the beginning there is something in combination. I write my first test and, following the method, I get my first error.
So I need to fix that situation, first by implementing MMModel class.
With this implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
The tests passes, things seem to go in the right way. Let’s face the second test. As it says every time we start a new game, a new combination, the next test seems obvious that it has to be something like:
1 2 3 4 5 6 7 8 9 10 |
|
But that only covers one iteration, and unit tests has to be independent on the contexts, that mean a random number of times, so let’s introduce a random number to repeat starts.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
And this implementation
1 2 3 |
|
Makes the test pass. Yes, you might think “Hey, that’s a trick. This is not a valid combination!!” and you’d be right, but don’t forget TDD says “Write the minimum amount of code that makes the test pass”, and that’s what we are doing. Later on we’ll find that we need to change this implementation to pass other tests, but we’ll be sure we are not breaking the rules with the following and more complex tests we need to pass.
It’s time for some refactoring and we’ll move the declaration of model to the setup method. As we need a new combination from the start, we’ll also move a call to start in the model inside the creation. We run the tests by Cmd+U and see all still works.
Next requirement is :
So the tests are :
1 2 3 4 5 6 7 8 9 10 11 12 |
|
And here we have our first need of re-coding a part of the source to be able to pass those two tests. Try to do it by yourself and if you can’t see how to do it, you can go and checkout this commit.
With the next requirement, things start becoming complicated and won’t be so easy in terms of coding.
Let’s write the test to fail.
1 2 3 4 5 6 7 8 |
|
Again all the challenge is inside start method in MMModel.m. It is a good practice to try to implement it by yourself. Once you are done, checkout Step 3 and you can compare your solution to mine and see how beautiful it is to see there are many ways to find a solution for the same problem. And remember to write the less possible code to pass the tests.
To not make this post eternal, I will just comment next requirement:
In this case we can’t write a test, at least in an easy way, about how to allow something. If opposite to this requirement it would be “The numbers in the combination can be repeated” it would be easy to traverse the digits and ensure there is no repetition, but as long as this is not a restriction, I won’t write a test for it. As usual, you can have a different opinion and write a test to verify it, I encourage you to do it and paste a comment explaining why you took that decision.
You’ll find the full code for this post in Step 4.
In the next post BDD - Mastermind : Preparation to make the UI Testable we’ll start preparing the views to implement it with BDD.
If you like it, please share! And leave me a comment if you have some time, I’d love to know this is helping someone ;)
]]>In this post we are going to walk through the process of designing how we are going to architecture it internally and start writing down the first specifications that later on will become tests. I decided to structure it the way a “non technical” person would describe what she wants and then move it to the world of Unit Testing and Acceptance Tests.
Let’s begin by revisiting the most important design pattern used in iOS Development, Model - View - Controller. The internal design we are going to implement follows the classic schema. The first decision to make here is where to put the logic. I’ve seen many designs that include the logic in the controller and leave the model just as a mere repository. My understanding is that the controller should act as the “where to take this” and “where to put that”, not as the container of “what happens when y put this” or “what should I obtain when I deliver this”.
So, here is the first decision, the logic of the game will live in the model. Let’s write some requirements the model has to follow.
These are the requirements to follow. As you can see I’ve simplified the mastermind rules in order to make this exercise more understandable. We are not trying to create the final app but to understand what are we doing.
Now that we have the model specified, let’s go for the behavior we want for the app. These requirements are written in natural language and then we’ll rewrite later on in gherkin sintax, which is the syntax used to describe the behavior that cucumber understands. As you will see, it is a very understandable syntax. Try to show the final result of the scenarios to a non technical person and see how easy she can understand and validate them, that’s the great advantage I find in this, it’s a bridge between devs and PO that both can understand and agree to a behavior with no interpretations and confusions.
Those could be the requirements. Note that we have to go to the very basic behavior to be sure nothing is left to no specification. If something is not explicitly defined, that means than nothing happens in that case.
Up to this point we have initial conditions. Let’s define the behavior to play.
The third group of specifications will be the behavior of the results and the reset of the game.
And this is all. We have created the specifications for all the rules and behaviors of the game. Of course we can define a lot more and be more exhaustive. But this is a good beginning.
In the next post BDD - Mastermind : TDD in the Model we’ll start implementing using TDD for the Model.
If you like it, please share! And leave me a comment if you have some time, I’d love to know this is helping someone ;)
]]>Last year I did a formation on iOS development. The final lessons consisted in creating a game, the Mastermind game. I think it is a good idea to use this example to build and app using TDD and BDD. Of course this process will not contain the full creation process with all details as it would take ages, even a book to do it, but I will include the headlines of the process with all the details and guides to complete the process, and of course with the code to do it.
Let’s start with it.
We want to create the classic mastermind game. For those that doesn’t know how top play Mastermind can take a look at wikipedia where the rules are very well explained.
In order to make this easier, let’s simplify some rules. We’ll make a fix number of games to play, let’s say nine, the codemaker will always be the iPhone and finally, there will be no points distribution, if the codebreaker guesses the pattern of colors before ten games, wins, otherwise loses.
Of course those restrictions can be released in the future, but for now, let’s do it this way.
The first job to be done is far from the keyboard. We all want to start typing and working with the mac and seeing how it is starting to look like we expect to see it, but the truth is that The better you prepare it all, the best result you’ll get.
So now let’s put our Product Owner hat on and let’s draw what we want. In this case, as we are going to create a game, we can start with the graphical part, because it will drive most of the subsequent user stories.
Drawn on paper it could look like something like this. I like to draw my first version with a pen or pencil so I can make easy and fast corrections as many times as I want. Once I am happy with the result, I will be able to proceed with more sophisticated tools or even ask a graphical designer to make a nice version of what I have on my mind to look as nicer as possible. But remember, one step at a time and don’t try starting to build your house by the roof.
The sketch contains all the information we need. It has a place to put the combinations. It has a place to show the result of the try. And it has enough space to repeat each try until the user gas the combination or consumes all the opportunities.
Easy right? Well now you can say you have not only an idea but also what it should look like. Next step is start with the analysis of what we’ve just drawn.
First thing we can identify is that there are four different zones that we can identify.
1 - Left column is different from the rest. It will contain the results of the last combination we played.
2 - Four columns at the right of the first column. They will contain each of the combination we’ve tried in chronological order.
3 - Cell content with a special control that contains the result of the combination composed by the four colors at its right.
4 - Row contents with four cells, each with a color representing a combination.
I know this analysis might seem too basic and simplistic, but believe me, simple analysis lead to simple and effective solutions and makes you not missing any part of your project. In fact engineering is that, dividing problems in smaller problems and those in more smaller until we are able to find a solution for each one and then reintegrate them in one big solution.
And that’s all for this post. In the next post BDD - Mastermind : Internal Design we’ll start writing the requirements for the graphic part so we can be able to transform them into scenarios we can test in our continuous integration system.
Please, don’t forget to share this post if you liked it.
]]>This post belongs to a series about Mac OS X Productivity Tips for Developers. Next post will be Applescript Automation & Automator Apps.
]]>During the chapter you become less and less scared about moving to this other shell and see all the benefits, from moving from one folder to another, themimgs the shell or listing the options a subcommand has.
Again we are in front of a master lesson by Tim Berglund and Mathew McCullogh.
This post belongs to a series about Mac OS X Productivity Tips for Developers. Next post will be Display Control.
]]>I decided to put this chapter together with the previous one because of its shortness. This is about how to use the clipboard from the command line as the title says. You never know how useful it can be until you realize the big amount of situations where it becomes a productivity improvement, not only to copy and paste data, but also to use commands and create gists with no mouse interaction.
This post belongs to a series about Mac OS X Productivity Tips for Developers. Next post will be Shell Tune-Ups .
]]>This post belongs to a series about Mac OS X Productivity Tips for Developers. Next post will be about Web Service Helpers.
]]>The second one is about the finder. I’ve complained many times about finder and all the functions I miss in it, but there is certainly a few tips you can use to make the job faster, easier and more effective. As usual they drive you through this topic in an easy and very understandable way.
This post belongs to a series about Mac OS X Productivity Tips for Developers. Next post will be about Saving in the cloud.
]]>Once again, Mathew and Tim showed me how wrong I was, explaining very well that behind Spotlight there is a lot more power using a sort of query language, that lets you filter by the existing, created and automated metadata that lives inside our system items, and how to take advantage of it to make it work in our favor without, once again, taking your hands out of the keyboard.
This post belongs to a series about Mac OS X Productivity Tips for Developers. Next post will be about Viewing with Quicklook and Moving with Finder, two short chapters that I am going to review together.
]]>This post belongs to a series about Mac OS X Productivity Tips for Developers. Next post will be about Searching with Spotlight.
]]>This post belongs to a series about Mac OS X Productivity Tips for Developers. Next post will be about Package Management.
]]>This post belongs to a series about Mac OS X Productivity Tips for Developers. Next post will be about File Formats.
]]>This chapter is focused on the terminal, that big unknown for many users, loved and hated in the same proportion, but needed at some point if you are or you are thinking about becoming a developer.
The chapter starts talking about iTerm2 and how to use it, set it up and customize to your preferences, but beyond that you get a series of tips to be able to improve your productivity and avoid errors that will save your butt in more than one situation.
At the end of the chapter the reveal a great ‘utility’ for your terminal that will make you love this video just for it and you’ll use for sure in your daily basis work, and not only that, they show you where to get more like them. Take a look at it, it’s worth it.
This post belongs to a series about Mac OS X Productivity Tips for Developers. Next post will be about Source Control Assistants.
]]>