[rspec-users] Game development: how to test interactions like an attack?

Justin Ko jko170 at gmail.com
Thu Feb 2 06:44:31 EST 2012


On Feb 2, 2012, at 2:20 AM, Romain Tribes wrote:

> Hello,
> 
> I'm writing webgames with Rails and I want to test my code (and even TDD) but I'm really stuck figuring what to test.
> I read a lot of articles on the subject but I still don't know what to do in my case: how to start?
> 
> For instance, a simple interaction in most game: a character attacks another one. What should be tested?
> With words, here is what I can say about an attack:
> 
> It's an action from an attacker to a target.
> The attacker may have a weapon and the target may have an armor.
> In order to be successful, the attacker must hit the target, according to the combat skill of each actor and the precision of the weapon.
> When the target is hit, it receives damages according to the attacker power, the weapon damages and the resistance.
> A part of these damages may be absorbed by it's armor.

What you just listed ^^ is the behavior of the system. The great thing about BDD is you can start _without_ needing to know the implementation details.

The first step you can take is to setup some high level, outside-in testing. These tests interact with your program the same way as a user would. You'll hear these tests called many different names: acceptance, integration, functional, application, system, etc. I don't believe there is a correct term anymore, as everyone interprets the definitions differently.

In the case of Ruby, you have excellent tools available for these tests: RSpec, MiniTest, Cucumber (used with RSpec or MiniTest). Personally, I prefer to use only RSpec, so let's use that as an example.

Pick a simple behavior to start off with. A good one is something that the user _has_ to do first. For example, in a Rails app, this would be signing up:

# project/spec/functional/signing_up_spec.rb

describe 'Signing up' do
  context 'by visiting the sign up page' do
    before { go_to_the_sign_up_page }

    context 'and submitting the sign up form with valid data' do
      before { submit_the_sign_up_form_with_valid_data }

      it 'redirects to the dashboard page' do
        expect_to_be_on_the_dashboard_page
      end
    end
  end
end

Great, now I have my first spec. Obviously, if you tried to run this, it would completely fail since you haven't written any implementation code.

At this point, writing more high level tests doesn't make sense because we haven't got the first one to pass. Let's focus on doing that.

Alright, so as we can see from our spec, the first thing it does is "visits the sign up page". Okay, we need a sign up page. The sign up page is a single entity, and we're no longer concerned with how it interacts with other parts of the system. Therefore, we need to drop down to the "unit" level, and subsequently create a unit test for this entity:

# project/spec/unit/sign_up_page_spec.rb

describe SignUpPage do
  context 'given a coupon code' do
    it 'sets a hidden field called "coupon_code" with its value as the code' do
      expect_a_hidden_field_with_a_particular_value
    end
  end
end

Notice how we are still focusing on behavior. The difference is, we are only concerned with the behavior of just this entity/unit, not on its role or interactions in the system. Because of this, you'll sometimes see people call them "isolated unit tests".

After you get the unit test to pass, you can check to see if the high level test can pass. The BDD process involves jumping back and forth between unit and high level tests. However, the high level tests are _always_ your guide. You drive the high level tests, and in turn they drive the unit tests.

I think this is enough to get you started, but looking at your post, this could be your first high level test:

describe 'Attacking' do
  let!(:attacker) { create_attacker }
  let!(:target) { create_target }

  context 'on the playing page' do
    before { go_to_the_playing_page }

    describe 'when an attacker hits a target' do
      before { hit_target(attacker, target) }

      it 'displays the damages on the target' do
        expect_page_to_display_the_correct_damage_amount
      end
    end
  end
end


> When the target is hit, it receives damages according to the attacker power, the weapon damages and the resistance.

> So, what could my specs be with that? I really can't start… :(
> 
> Thanks for your help!
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list