6 ms·
The way Clojure mitigates this is by having a REPL. Whenever I work on any code I can always run it immediately in the context of the application. Let's say I'
by yogthos 13y ago
The way Clojure mitigates this is by having a REPL. Whenever I work on any code I can always run it immediately in the context of the application.
Let's say I'm refactoring a function, I can run it to see what it actually does and I can write a new function and test it immediately on the spot to make sure it has the same behavior.
When you're working in a REPL you always have confidence that whatever change you made does what you want immediately. There's no recompile cycle, you don't have to restart your application and build up the state to see what effect the change has.
This allows you to refactor things and be very confident that you're not breaking anything. Coupled with high level integration tests you can be confident that all the use cases work correctly without having to have a ton of unit tests.
Having worked with Clojure it really shocks me that most modern languages do not have any REPL integrating in the editor and you still have the code/compile/run cycles.
- pjmlp 13y agoI use languages with REPL support since 1995. A REPL helps interactive development a lot, but it is by no means a substitute for testing enterprise class applications. You cannot cover all use cases of your code. Specially when other departments using your libraries make assumptions about your code behavior.
- yogthos 13y agoI didn't say it was a substitute for testing. My point was that it lets you know what the code is doing immediately. This doesn't remove the need for tests, but it means that you don't have to run tests every time you make a change.
- mercurial 13y agoLet's say you change your function by adding a new parameter, or you modify the order/type of existing parameters. How does your REPL save you, then? You can make sure that your new function works correctly, but not that all call sites are correct. In my experience, not that many codebases have "high-level integration tests", which are kind of an orthogonal issue compared to unit tests (you still need unit tests if you want maintainable Haskell, in spite of the type system and REPL).
- yogthos 13y agoThe REPL lets you test any call sites immediately after you make a change. I do this all the time at work. Let's say I change a function that accesses the database, I can update the function then update the call sites and run them right there and then. At least in Clojure, the REPL is integrated in the IDE. I can use the IDE to tell me where the call sites are what references the function, jump to definition, etc. Then I can send code from the editor directly to the REPL to test it out. I use Intellij with the Cursive (http://cursiveclojure.com/ http://cursiveclojure.com/) plugin, but you can do the same thing with Emacs and Eclipse. My experience is that unit tests make sense in some scenarios, but not in every situation. On the other hand, high level integration tests act as a contract for your application. You should have these regardless of whether you're working with a dynamic or a static language.
- mercurial 13y ago> The REPL lets you test any call sites immediately after you make a change. I do this all the time at work. Let's say I change a function that accesses the database, I can update the function then update the call sites and run them right there and then. At least the ones you know about. Now, take your codebase to 100k lines, 75% of which you didn't write. Good luck. Wrt to integration tests: they're a pain to set up, and the complexity creeps it really easily. It's straightforward to unit-test edge cases, but the combination of layers makes it much more difficult to rely on integration tests for this kind of thing. Plus, integration tests usually take a long time to run. Rapid feedback is important.
- yogthos 13y agoThe code base I'm working on has been developed for about 3 years by a team of 4 people. I have no trouble navigating it, nor does anybody else on the team. If you're working with a half decent IDE, it can do things like tracking down function usages for you very easily. >Wrt to integration tests: they're a pain to set up, and the complexity creeps it really easily. That has not been my experience at all. Clojure has very nice testing frameworks that makes this trivial. >It's straightforward to unit-test edge cases, but the combination of layers makes it much more difficult to rely on integration tests for this kind of thing. The REPL allows doing a lot of what unit tests are normally used for. When you make a change you test it live in the REPL. This is no different from running a unit test. >Plus, integration tests usually take a long time to run. Rapid feedback is important. Hence why you don't run them all the time. The REPL provides you with rapid feedback, much more rapid than running unit tests I might add. Meanwhile, the integration tests are used for overall sanity testing.