Hot answers tagged

99

Testing dogmatism aside, the real question is whether it provides value to unit test complex regular expressions. It seems pretty clear that it does provide value (regardless of whether the regex is part of a public interface) if the regex is complex enough, since it allows you to find and reproduce bugs and prevent against regressions.


53

You're looking for tests that check for regressions. i.e. breaking some existing behaviour. I would start by identifying at what level that behaviour will remain the same, and that the interface driving that behaviour will remain the same, and start putting in tests at that point. You now have some tests that will assert that whatever you do below this ...


38

The recommended practice is to start with writing "pin-down tests" that test the current behaviour of the code, possibly including bugs, but without requiring you to descend into the madness of discerning whether a given behaviour that violates requirements documents is a bug, workaround for something you're not aware of, or represents an undocumented change ...


33

Yes. In this case, simply ensure that the web service returns whatever data the mock provides. There is value in doing this, even if it seems trivial or boring. What if someone later adds logic that changes the data? Boom: failed test. Now you have a discussion about whether the web service or unit test needs to be updated. That is better than ...


26

Removing a public method is not "refactoring" -- refactoring is changing the implementation while continuing to pass existing tests. However, removing an unneeded method is a perfectly reasonable design change. TDD draws this out to some extent, because in reviewing the tests, you may observe that it's testing an unneeded method. The tests are driving your ...


22

This is a wonderful idea, with one caveat. Don't replace developer written tests with reviewer written tests. Have your reviewers look for corner cases and inputs that will break the code. In other words, have them try to write new tests that the original developer didn't think to write. Writing characterization tests is an absolutely wonderful way to gain ...


21

Regex can be a powerful tool, but it is not a tool you can trust to just still work if you make even minor changes to complex regexes. So create lots of tests that documents the cases that it should cover. And create lots of tests that documents cases it should fail, if it is used for validation. Whenever you need to change your regexes you add the new ...


18

I don't think the idea is entirely without merit - however, the main benefit of the TDD et al is that problems are found early. The developer is also best placed to spot which corner cases may require specific attention. If this is left until the code review, then there is a risk this knowledge could be lost. Writing tests during the code review would ...


16

Yes, of course. The easiest code to read is that which isn't there. That said, refactoring generally means improving the code without changing its behavior. If you think of something that improves the code, just do it. There's no need to fit it into some pigeon hole before you're allowed to do it.


13

I suggest - if you haven't already - reading both Working Effectively With Legacy Code as well as Refactoring - Improving the Design of Existing Code. [..] The problem it appears to me is that when I do refactor then those tests will break as I'm changing where certain logic is done and the tests will be written with the previous structure in mind ...


12

There are some posibilites, how to mock static methods in PHP, the best solution I have used is the AspectMock library, which can be pulled through composer (how to mock static methods is quite understandable from the documentation). However, it's a last-minute fix for a problem which should be fixed in a different way. If you still want to unit test the ...


10

What I'd do in this situation is to mark the failing tests as "ignored" - that way you still have the test so that you know what you need to fix in future, but you're not going to end up with broken builds. If you also tag each test with the issue tracker reference for fixing the issue, that gives you an easy way to tie things together.


9

In fact f() replaces all calls to b() with the exception of the unit tests that defined / described b() IMHO the typical TDD cycle will look like this: write failing tests for f() (probably based on the tests for b()): tests go red implement f() -> tests become green refactor: -> remove b() and all tests for b() For the last step, you might consider ...


7

Wouldn't it be beneficial to write tests during code review, by the person doing the review? I have found that a good time to write tests is when you realize you need a test for a situation. Task switching for computers is expensive - even more-so for humans. At this point in time, you generally have a good understanding of the requirements and ...


6

I agree with @RobbieDee's answer but I have a bit more to add. If you really like this idea, why not have the same people write the tests before the code as executable acceptance criteria for the user story? That would do the same thing, still keep the feedback short and get everyone to have a discussion around the story ,which I think would be of greater ...


5

Don't write strict unit tests where you mock all the dependencies. Some people will tell you these aren't real unit tests. Ignore them. These tests are useful, and that's what matters. Let's look at your example: public class MyDocumentService { ... public List<Document> findAllDocuments() { DataResultSet rs = ...


5

Do you inject the target repository (i.e. are you using dependency injection) If so, you should be able to assert that _targetRepository.Add(officers) is called by querying your mocked target repository. This is a common problem and pattern for a solution in testing. Dependency injection helps you solve this since your test can provide the mocked ...


5

Before you get the answer you are looking for, you need to decide on where you/your company stands in the spectrum of Testing: On the far right is something like Test Driven Development, which says for every line of code you write, you must have a failing test that some change or new line of code can fix. Somewhere in the middle is where other schools of ...


4

Your unit tests are in a separate project and serve a separate function from your main code, so putting them into a separate namespace makes the most sense to me. If you're considering putting them into the same namespace just to save the using line, then don't. Less code is good, clearer code is better.


4

Full disclosure: I am one of the participants in the discussion. The repository's master branch is not it's master branch. The merge into master does not serve any "actual purpose" and that branch is not doing things a branch should do (namely move). You're abusing this branch as a Tag to the latest release. Instead of using a branch, use a Tag. When ...


4

First, I would suggest to split this up into separate methods: public function validate($value, Constraint $constraint) { $totalCount = QueryTotal($value); ShowMessageWhenTotalExceedsMaximum($totalCount,$constraint); } private function QueryTotal($value) { $searchEntity = EmailAlertToSearchAdapter::adapt($value); $queryBuilder = ...


4

Yes, it is. The best, most bug-free, most readable code is the code that doesn't exist. Strive to write as much non-code as possible while fulfilling your requirements.


4

The tests should be relatively easy to write then. However, through the process of writing tests, you often find out it's not as trivial as you thought. There are often boundary or race conditions you miss that come to the surface during writing automated tests, conditions that are really difficult to hit in a production environment. Also, if you end up ...


3

As you say, if you change the behaviour then it is a transformation and not a refactor. At what level you change the behaviour is what makes the difference. If there are no formal tests at the highest level then try and find a set of requirements that clients (calling code or humans) that need to stay the same after your redesign for your code to be ...


3

tl;dr Don't write unit tests. Write tests at a more appropriate level. Given your working definition of refactoring: you don't change what your software does, you change how it does it there is very wide spectrum. On one end is a self-contained change to particular method, perhaps using a more efficient algorithm. On the other end is porting to ...


3

Like you say, if you're running a TDD team, then this is moot since the code should already be tested. Overall I don't think this is all that great an idea, but it depends on your current approach and what works for you. Basically, the problem I see is that you lose the "short feedback loop" advantage of tests. Getting instant notification the moment you ...


3

Regular expressions are code along with the rest of your application. You should test that the code overall does what you expect it to do. This has several purposes: Test are runnable documentation. It clearly demonstrates what you need the code to do. If it is tested it is important. Future maintainers can be certain that if they modify it, the tests ...


3

Say you just hired me. Say I update 5 different things at once. Now something is broken. It happens to be this AngularJS Rest service. But we don't know that. What test could you have written in the past that would help us diagnose the problem today? You can mock your REST endpoint. Something stable that just gives the service something to talk to ...


3

If you donot like the additional constructor arguments for the dependencies you need a DI-Container to handle the instance creation for you. You can use either an existing di-container framework or implement a poor mans version on your own public PoorMansDiContainer : IPoorMansDiContainer { private IService mService = null; private IFooService ...


2

Your certainly on the right track. For my projects I use: "check" to unit test all method (including as many code paths as I can - have time for). This runs super fast and gives me confidence that the parts of my application are doing what I expect. "Valgrind" to check the memory usage of the final application while running system/regression tests. This is ...



Only top voted, non community-wiki answers of a minimum length are eligible