Behavior Driven Development Plugins

Behavior Driven Development (BDD) is one of the most amazing things ever. It’s the difference between:

ASSERT_EQL 1, 2

and

1.should equal(2)

Since sponge is an abstraction layer, it should really offer some way to write behavior tests.

What’s wrong with just using ScalaTest/Spock? I think extension methods / implicit conversions are a much more elegant way to handle this than bloating every Sponge-provided class (also, how would you do this for externally defined types or primitives?).

I’m not saying replace ScalaTest or Spock, I’m saying write matchers that are sponge specific.

So why do these matchers belong in Sponge itself? This is generic test-specific boilerplate, generic test-specific code should go in the testing framework, not into something that is available at runtime. IMO, Sponge should be primarily targetting making plugins play nice together, plugin testing code is something that should only very rarely interact with any other plugins’ testing code, and thus the risk for conflict is small enough that it doesn’t need to be solved centrally (compare this to, say, permissions which is something that almost every plugin needs to be integrated to at the core).

I didn’t mean in the API or even the implementation. Wherever you want to put it, it should be official and promoted. BDD is something that MC has been lacking and needs to have.

No, testing is something that is up to each plugin.

So you’re saying everybody should write identical matchers in their own codebase? This is why we end up with a bajillion “corelib” mods, because there aren’t any standards.

No, I’m saying everyone should use whatever testing framework they’re familiar with, which already provides generic matchers.

1 Like

I’m confused - what are these custom matchers that are so important to you? Why force your way of developing plugins down everyone’s throats? And why is your Maslow’s Hammer better than mine (or someone else’s)? The zealotry is a bit icky…

Edit: And why are the Hamcrest matchers not good enough?

2 Likes

TDD/BDD isn’t “my way”, it is the standard way.

The whole point of matchers is to make something read like english. Saying:

before {
 myBlock.createNewBlock()
}

expect(world.blockAtCoords(x, y, z)).should beInstanceOf(MyBlock)

vs

expect(myBlock.createNewBlock().to createNewBlockAtCoords(x, y, z, MyBlock)

The latter is much more semantic.

TDD is not “the standard way”. It’s a very specific method of developing software that promotes the idea of only writing code that has a test requiring its existence. I know exaclty what it is (and I’ve used it to great lengths, both in personally projects and through my education), but I don’t understand why you think that it is a de facto standard way of developing software. Sounds like you’re living in a bubble. The real world does not work the way academia wants it to work, and while TDD is a great way to write robust software, it is by no means “the only way”. I think you’re forgetting just how tedious and time-consuming it is when you start out. Most people don’t have that patience, and a lot of people don’t think it’s necessary. But that’s besides the point - who are you to tell other people how to develop their software? Like I said, the zealotry is icky. I’m all for encouraging good practices, but I’m very much against forcing people to do what you want.

And like I asked, why are the Hamcrest matchers not good enough? What outrageously convoluted code do you write that requires an extensive API-side collection of custom matchers? I’ve never been in a situation where the basic matchers and a little bit of clever software design wasn’t good enough. Besides, I completely disagree. I think the quest for programming languages to look like English is ridiculous. I like a concise, easy-to-read language just as much as the next guy, but I don’t think mutilating the main paradigm of the language you work in is the way to go. It creates more confusion than it has to, and makes things look “weird”.

I want to stress the fact that an opinion cannot constitute a rule. “How to develop software” is just as much based on strong opinion as “which programming language is better”, and just as petty as the debate of whether or not my dad can beat your dad.

PS: My dad can beat your dad.

2 Likes

How would offering test matchers be forcing people to write tests? That’s like if I were to offer you some cake, do you have to eat it? no. I’m not forcing you to eat the cake, but if you wanted cake wouldn’t that be great to have it ready for you?

I specifically recall you saying…

That sounds like a gateway drug to forcing people into your way of thinking.

I’m still waiting for an argument as to why custom matchers are even needed in the first place. What, specifically, is it that you cannot do with standard JUnit, Hamcrest, and a mocking framework? Why are you so desperate to have these custom matchers implemented? And why is it the Sponge project’s responsibility to provide them?

But alright, I’ll play along. If we’re just adding crap to Sponge willy-nilly because someone thinks “that’s nifty for me”, I want the Scala and Clojure runtimes bundled with Sponge, as well as an interpreter for brainfuck, because why not? I also want all of the Apache Commons and Google Guava libraries, Colt, Trove, Lombok, Netty, and all the Android APIs from 14 and up.

2 Likes

Promoting something is not forcing it. Don’t put these matchers in the sponge repo, that’s idiotic. There can be a sponge-matchers lib which should be in whatever the default build script is for plugins.

Nothing. In fact, I can do anything with a turing machine. Now, should I do everything with a turing machine? No, that would be incredibly complex. The point of matches are to make it read better, to be more semantic.

Here’s a ruby example of what application specific matchers can do:

before:

it "should validate presence of name" do
  person.name = nil
  person.should_not be_valid
end

after:

it { should validate_presence_of(:name) }

Why would I do the former if I can do it all in a single line? Same thing with sponge, why can’t we make it easier to do tasks that will be repeated?

Okay. Now read what I wrote again.

Here’s a Python example of what a for-loop can look like:

for x in range(1, 5):
    print "%d Mississippi" % (x)

I’m failing to understand your point, because you keep derailing with seemingly unrelated examples, and arguments that degenerate to “we should do this because I say so”. It’s detrimental to the health of the debate, because you’re coming across as irrational and stubborn. Stay on the ball, and explain why it is the responsibility of the Sponge project to provide a full-blown feature set for something you can’t even provide relevant use cases for. And please explain exactly what the implementation and maintenance aspect is, because you’ve gone from saying Sponge should provide and promote it to saying it can just be something “off to the side”. I’m struggling to see why you can’t just implement and make available these matchers yourself. Does that not solve all your problems (unless another problem is that you don’t know how to write them yourself)?

So… the concept of BDD is now different between Ruby and Java?

Sponge, as in the organization. The people who write the code and understand best how it works. The complaint was that you shouldn’t put the matchers and tests in the sponge distribution jar, put it wherever the hell you want, distribute it separately, together, who cares, it doesn’t matter.

expect(myBlock.createNewBlock().to createNewBlockAtCoords(x, y, z, MyBlock)

It’s impossible to provide specific use cases yet because the API isn’t ready. But I can assure you, there will be things that re going to behave in certain ways and different things, in different ways. Ya know what? Maybe there will be things that use other things that behave in a certain way.

As sponge changes, the testing matchers will too. The Sponge team knows what’s changing (surprise!) and can update/add matchers easier. It also promotes good testing more if they provide matchers that make it easier and then tell people that they should be writing tests (Arguing that tests aren’t beneficial is moronic; don’t say it’s a coding preference, there’s plenty of science to back it up)

I gave a ruby example because I’m very familiar with rspec, I don’t know the proper syntax for ScalaTest (or any of the other options) so I just gave one I’m familiar with. ScalaTest seems to looks similar so it shouldn’t be hard to understand what my rspec example does.

The concept of TDD isn’t different, but the practicalities are. Are you not asking specifically for actual implementations of these concepts? How is it not relevant that what you’re trying to do is actually going to benefit you in the language you’re going to use?

You are the one who claims this feature set to be a must, so the responsibility to implement and maintain it is yours. If you see a problem, you own it. Is Sponge not a community-driven, open source project? Nothing keeps you from doing this, and who better to do it than you, who actually claims to need it? Don’t understand how the necessary Sponge internals work? Great! That’s a wonderful opportunity to get involved! Buckle down and get rolling.

This syntax makes absolutely no sense to me (unmatched parentheses, for one), and it honestly looks like you’re making a perfect example of bad software design, where you aren’t stubbing and mocking where you should be (and by extension, you aren’t creating the right abstractions). In this case, myBlock must have a reference to a world on which the necessary methods are called, in which case you mock the world, feed it to the block, call your method, and then verify that the method was called. This standard way of unit testing is impossible to beat when it comes to readability for people new to the techniques and the source code. No matter of laziness can justify convoluting code to the point where it’s impossible to understand unless you know about all the “black magic” going on, and no, making your programming language look more like English is not equivalent to improved readability (as argued previously).

You seriously need to come up with an actual SSCCE to gain any ground here. If you can’t do that, you don’t need this as badly as you think you do. Again, I will make a reference to Maslow’s Hammer and your seemingly zealous attitude towards this thing. I’m struggling to understand why your particular niche (and it sure is a niche) is so much more important, and I honestly don’t think you can ever push the responsibility of implementing and maintaining this feature set on to the core Sponge team. I personally think it’s a complete waste of precious resources (man hours) to focus on something devoid of strong justification.

No one has argued that tests aren’t beneficial; you, however, seem to be arguing that these special matchers are necessary for TDD to be an attractive software development technique, and I am arguing the contrary. But yes, unit testing is indeed a preference - some like it, some don’t. Some do it, some don’t. Some develop efficiently with TDD, some don’t, and others just don’t have the patience to get into it (just like some people don’t have the patience to deal with and grok text editors like Emacs and Vim). There is no science to “back up” an opinion, a preference, or an affinity, because none of them can constitute a rule. Please don’t resort to pseudo-scientific drivel to try to prove a point, and please stay on the ball.

I think providing examples in Java is going to help your case a lot more than providing examples in languages that have absolutely nothing to do with the project or the language that plugins are actually going to be written in by most people. I also think you might benefit from actually learning Java, JUnit, Hamcrest, and a mocking framework like Mockito. This entire paragraph seriously just made it sound like you don’t know anything about unit testing in Java, and jumped the gun without checking out what’s available. If that’s the case, this whole thing makes a lot more sense, and I highly advise you to get studying.

1 Like