Testing __set and __get
Moderator: General Moderators
Testing __set and __get
Using simpletest, what would be a sensible way to test that a class is definitely using __set and __get rather than giving a user public access to a variable? I'm really only just starting out with TDD so I can't think of a decent way to assert that the returned value is going through __get without modifying it in a way that changes the output variable (eg appends "GET" to it) and then assert that the value is "GETvalue" ... that seems a bit illogical though because it wouldn't be testing the real code.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Testing __set and __get
You are not really testing the code as much as the results of the code. If a value goes in and then come out with the expected value, it shouldn't matter to the test whether $this->foo was a real property or via __get()/__set(). If you tested how it got the value then you would close the door on refactoring.
(#10850)
Re: Testing __set and __get
Exactly as above, you are testing behaviour, not specifics. If an object receives via $obj->foo, and does what is expected, it doesn't matter if it's a "real" property, or via __set/__get.
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
Re: Testing __set and __get
What they said
And the *reason* you want to avoid checking that it's done with __get() and __set() is because you'll use your tests as a safety net when you come to refactor/optimize. The tests tell you that your system still behaves as expected so every time you make a change to clean up the underlying code you'll run the tests to make sure that change didn't change the behaviour of the code (unless the change was supposed to change behaviour... then inevitably some tests will fail). If, as part of refactoring/optimizing you decide to stop using __get() and __set() then your tests will fail even though the behaviour of the SUT is still correct. It's one of the big reasons people give up on unit testing in the early stages since that type of thing leads to high test maintenance costs and you stop trusting your tests since you're so used to seeing them cry wolf.
And the *reason* you want to avoid checking that it's done with __get() and __set() is because you'll use your tests as a safety net when you come to refactor/optimize. The tests tell you that your system still behaves as expected so every time you make a change to clean up the underlying code you'll run the tests to make sure that change didn't change the behaviour of the code (unless the change was supposed to change behaviour... then inevitably some tests will fail). If, as part of refactoring/optimizing you decide to stop using __get() and __set() then your tests will fail even though the behaviour of the SUT is still correct. It's one of the big reasons people give up on unit testing in the early stages since that type of thing leads to high test maintenance costs and you stop trusting your tests since you're so used to seeing them cry wolf.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Testing __set and __get
This is also the reason why testing reduces the need for some kinds of documentation. As you can see, it is a fine line between expectation and specification. As your tests become the specification of the application, there is a reduced need for traditional specs.
(#10850)
Re: Testing __set and __get
So in TDD it doesn't actually matter how the code passes the test, so long as it passes, right? That's going to take quite a lot of getting used to I think.
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
Re: Testing __set and __get
It's the hardest thing to get used to believe meonion2k wrote:So in TDD it doesn't actually matter how the code passes the test, so long as it passes, right? That's going to take quite a lot of getting used to I think.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Testing __set and __get
Actually in TDD how the code passes the test is the thing you are now free to focus on. That's because these tests take care of the tedious process of determining whether the code passes the test. TDD frees you to focus on the design of the code, because each iteration you don't have to shift your brain into acceptance/regressing testing mode. Unit testing supports refactoring in the same way.onion2k wrote:So in TDD it doesn't actually matter how the code passes the test, so long as it passes, right? That's going to take quite a lot of getting used to I think.
So I think you are thinking about it backwards.
(#10850)
Re: Testing __set and __get
Yeah, that's what I can see as a big advantage of it, and that's why I'm learning how to do it. But it requires undoing what I've spent the past 15 years of development learning to do - write code with a detailed get-it-right-first-time goal. I think that's going to be the tricky bit - learning is easy, unlearning is hard.arborint wrote:Remember, TDD is a design methodology that allows you to break designing down in to a manageable iterative process, rather that the old style of impossibly trying to get the whole design right up front.
Fortunately though, while it'll be hard for me, it should make it a lot easier to sell the process to my boss when I've learnt it and want to start using it on client projects. By the sounds of it TDD is a more client oriented methodology. Clients like an iterative process where they can change things along the way; specification changes are something that makes developing code the "old" way quite tiresome. Anything that can help me deal with the whims of silly clients better has to be a good thing.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Testing __set and __get
I really think experienced programmers who never learned to test should put TDD aside a little and just write Unit Tests for their classes. Start with the ones you reuse and change a lot. The first thing you will notice is that you will find some bugs.
You may then find that you will start using the Unit Tests when you make changes. That will give you the experience of changing/creating code with tests supporting your work. Once you have done that a while, and if writing Unit Test starts to feel more natural to you, then try writing some tests first and coding to the tests for some new code you are working on.
(#10850)
Re: Testing __set and __get
Truth be told, that's what I'm doing. I'm rewriting Thumbnail using PHP5 and unit tests. When I'm happy with that I'm going to kick off my idea for a new photo gallery app using TDD.