Live data from Hacker News

Ask HN: I have a mental block designing software. Time to quit?

news.ycombinator.com

61–70 of 89 posts

Re: Ask HN: I have a mental block designing software. Time to quit?

#61
post #60
post #56

Earlier quoted context omitted.

> However, you really do need some automated testing. How would you distinguish automated testing from TDD? > If part of your burnout here is that you are just [expletive] tired of making changes in one bit of the code just for it to create 6 more bugs in the rest of it, automated testing is the core solution to that. I do so much legacy maintenance/development, and yes this would make my life a lot easier. Not for m…

"How would you distinguish automated testing from TDD?" I would consider the distinguishing characteristic of TDD is that you write the tests first. There's varying levels of strictness there from little more than that restriction, to varying levels of dogmatism on writing code that only makes the test pass. I consider this a great way for a new programmer to learn how to really design code. In fact it's one of the o…

Thank you, that makes sense and why TDD is so worthwhile for me to start with.

For external services (I rarely write code that doesn't rely on at least one SOAP endpoint) is there any alternative to mocking the service and the response data? And then should your tests also verify that the remote service works according to its contract?

As it would affect data in the live system, I cannot think of a way to safely do it, but 3rd party systems have 'changed' their behaviours before now, and that's a horrible bug to track down.

Re: Ask HN: I have a mental block designing software. Time to quit?

#62
post #58
post #41

Earlier quoted context omitted.

Testing. I have never done TDD; I put it off in the beginning as an extra cost to clients (or time lost for me), and then when it became trendy I (as ever) disliked the trend :) Ian Cooper sums up my thoughts better than anyone else: https://vimeo.com/68375232 I'm doing a rewrite of a small project and that seems ideal to give it a go. To me functional testing is much more appealing, testing a simulated user's experi…

First, that alleged "extra cost" is the #1 myth. It might be true of test-last (code then test, anti-TDD; whatever it's called)-- I am not sure because I've never tested that way and that process is transparently ineffective if you take a very structured approach to the process (more later). I've been at a place where I also believed the same thing but since then I've built larger and larger systems and felt these pa…

Awesome! I wouldn't say my logical decisions are so cleanly cut from the UI as you'd wish (there's client-side and server-side logic, and an interplay between the two), but apart from that I can apply what you've written. Forcing myself to refactor rather than "making progress" is going to be a mindshift.

A couple of questions:

1) Considering a CRUD app: what do you unit test? I get TDD/automated testing for algorithms & libraries (I've actually done that, to verify outputs match a given input). But for application code?

2) For external services (I rarely write code that doesn't rely on at least one SOAP endpoint) is there any alternative to mocking the entire service and creating response data? That sounds painful (though worthwhile, subject to the issues in the next paragraph happening).

And then should your tests also verify that the remote service works according to its contract? As it would affect data in the live system, I cannot think of a way to safely do it, but 3rd party systems have 'changed' their behaviours before now, and that's a horrible bug to track down.

Re: Ask HN: I have a mental block designing software. Time to quit?

#63
post #61
post #60

Earlier quoted context omitted.

"How would you distinguish automated testing from TDD?" I would consider the distinguishing characteristic of TDD is that you write the tests first. There's varying levels of strictness there from little more than that restriction, to varying levels of dogmatism on writing code that only makes the test pass. I consider this a great way for a new programmer to learn how to really design code. In fact it's one of the o…

Thank you, that makes sense and why TDD is so worthwhile for me to start with. For external services (I rarely write code that doesn't rely on at least one SOAP endpoint) is there any alternative to mocking the service and the response data? And then should your tests also verify that the remote service works according to its contract? As it would affect data in the live system, I cannot think of a way to safely do i…

"For external services (I rarely write code that doesn't rely on at least one SOAP endpoint) is there any alternative to mocking the service and the response data?"

In practice, no. Though I prefer some variant to dependency injection to "mocking". I consider the testability a first-class concern and code accordingly. Exactly how this manifests varies suprisingly widely between various languages. You don't mention your language, so I don't have specifics.

"And then should your tests also verify that the remote service works according to its contract?"

Yes, but rather than thinking of that as "automated testing", you're better off thinking of that as "service monitoring" that happens to look like automated testing. Consider something like: http://n8v.enteuxis.org/2011/06/integrating-nagios-with-test...

Re: Ask HN: I have a mental block designing software. Time to quit?

#65
post #62
post #58

Earlier quoted context omitted.

First, that alleged "extra cost" is the #1 myth. It might be true of test-last (code then test, anti-TDD; whatever it's called)-- I am not sure because I've never tested that way and that process is transparently ineffective if you take a very structured approach to the process (more later). I've been at a place where I also believed the same thing but since then I've built larger and larger systems and felt these pa…

Awesome! I wouldn't say my logical decisions are so cleanly cut from the UI as you'd wish (there's client-side and server-side logic, and an interplay between the two), but apart from that I can apply what you've written. Forcing myself to refactor rather than "making progress" is going to be a mindshift. A couple of questions: 1) Considering a CRUD app: what do you unit test? I get TDD/automated testing for algorith…

Even an AJAX endpoint should be tested! Not at the controller level because the controller is the consumer, the JSON/XML output is your HTML template (just a converted structure) so if the contents are correct then it's reasonable to expect the JSON/XML is correct if you're using a standardized way of rendering it. And you could test your client-side JS to ensure it works too, starting with the "most degenerate" cases such as a 500 or 404.

> Forcing myself to refactor rather than "making progress" is going to be a mindshift.

Indeed. It's like being an ex-heroin addict or something... but when you get to a point where a project is mature, you appreciate your prior restraint every single day. Think about it more like a tank rolling forward, powerful and hard to stop. Not so much like a bullet train that might derail at the next bend.

I have the tightest testing requirements on the most internal components; business logic at the center. Leaf nodes have the least testing applied, so for example: - (Web/HTML) Templates are dumb, they get hit @ manual, browser-based V&V but nowhere else; nothing is leafier than this - Controllers basically just inject values into templates, my controllers are so simple that I actually only test the number of variables I am binding. This sounds so lazy it doesn't seem like it could provide anything but this has worked shockingly well for me (yes, even alerted me to oversights) because there is absolutely minimal logic in the controller, often boiling down to decisions about what to bind based upon a result. This is the node connecting the leaf and the branch, it's a tiny little thing. I usually test their display method and make sure they inject the correct number of variables. If I can do that and my factory (which is effectively the integration test for this unit) can create the object then I consider the controller working. If there's anything else which could fail, it doesn't belong in the controller.

At the other end of the spectrum are things at the core of your system which are obviously wanting of stringent testing like: - Business logic - Billing

This is a balance you have to strike but be consistent with whatever you choose.

Regarding CRUD and also applicable to APIs, separate your use of those things from the logic which operates on their results. So if you're writing something which uses the filesystem for CRUD you want to get ONLY the CRUD isolated in one layer. If you look at that CRUD class you won't be able to determine anything about the larger system or its purpose; the CRUD class will only deal with file creation/reading/update/delete and nothing else. It doesn't consider, manipulate, iterate, process or do anything with the contents. If you truly isolate that level then you can test your ENTIRE system (each action in isolation) and ensure the CRUD calls are made as expected, without touching disk.

As soon as you isolate the statefulness of the filesystem or database or remote service, testing is easy because (assuming you inject dependencies so they aren't hardwired) you can replace the CRUD service with a mock which will affirmatively pass or fail with a specified result at your command. If you can "play God" with return values like that then you can test the logic of that unit without restriction, hindrance or interference. What happens to this component if the CRUD class can't open the file? Just write a new test for it and mock CRUD's state to the same it is when it can't find the file. Assert what you want to happen. If it doesn't work as expected (the test fails) then you can fix the problem and prove that you didn't break anything else while resolving that issue by running against all of the previously-passing tests. If the test passed, you can keep the test and ensure the behavior remains unchanged through future edits.

APIs are difficult because they can change and their natures can be very different. Integrating with a local or regional company doesn't often resemble the experience of integrating with a giant like Google for example.

I would not test Google's API, period. When dealing with smaller companies however, it's a sticky kind of thing. One particular company I've integrated with breaks their API almost quarterly. If you often find yourself in a situation where the API breaks, even 1-2 times a year... I actually might recommend testing the API against an internalized test double. The internal mock gives you fast tests but importantly also becomes a check against which you can run the API. For APIs, testing is only worthwhile if you're interested in that second benefit. That said, it has a really nice benefit of making sure your mocked service comports with the interface of the service itself. It's a judgement call. As you mentioned, tracking down bugs in a 3rd party API is an utter nightmare.

Unfortunately I don't know a better way to mock an API than providing dummy results. These are the least fun tests to write but important to ensure stable interoperability. You should be using information-hiding to limit complexity at each level and hopefully after an abstraction or two you no longer need the API directly anyhow. If you don't have a test environment for the API at all I'd talk to the provider and/or consider moving to something else. At that point I'd even consider doing something in-house if necessary.

Re: Ask HN: I have a mental block designing software. Time to quit?

#66

What you're describing to me is you've built a very solid structure for reasoning about programs, but it is too rigid, and too focused. I would heartily recommend learning a new language. You need to shake things up a bit. Two reasons: 1. https://www.wikiwand.com/en/Linguistic_relativity - Our language shapes our thought. This is true for spoken and programming languages. 2. You cannot properly understand a language…

This is the first thing that came to my mind as well. Learning a new language surely shakes things up.

Re: Ask HN: I have a mental block designing software. Time to quit?

#67
You're thinking about it wrong. Don't think of it as "prototyping" or "just works". If it just works, you're done, there's no need to rewrite it to make it enterprisey.

What about it needs fixing? If it works for 100 items but not a million then fix that. If it works but is difficult for others to change the code, rearrange things until it's clearer. If it works by using some weird 3rd party dependency that wouldn't be easy to deploy and update, just remove that dependency, etc. If it works but you don't have an easy way to build or deploy it, then work on the build system. If it's buggy, fix the bugs.

Don't make things more abstract just for the sake of abstraction. Don't add message passing or enterprise logging just because they're enterprisey. Ask what problem you are trying to solve by adding these.

Re: Ask HN: I have a mental block designing software. Time to quit?

#68
post #5

https://www.youtube.com/watch?v=GAFZcYlO5S0 https://www.youtube.com/watch?v=iukBMY4apvI (javascript module workflow that helped me (frontend dev) to transition to modules) help?

Watching Simon Brown now & will look at his book too, thanks. To take the current project, I have a CMS, Salesforce and ExactTarget. I'm writing the glue to automate taking new content from the CMS, finding SF users with the right permissions to see it, and emailing it to them via ExactTarget. All good & working until... do I model it as 3 objects? Which object is responsible for creating the DataTable at ExactTarget…

In my opinion it's better to define criteria first and then evaluate possible solutions against them. What is more important for your code - to be fast, correct, easy to understand, fix or extend? How each possible solution scores on these scales?

Re: Ask HN: I have a mental block designing software. Time to quit?

#69

What you're describing to me is you've built a very solid structure for reasoning about programs, but it is too rigid, and too focused. I would heartily recommend learning a new language. You need to shake things up a bit. Two reasons: 1. https://www.wikiwand.com/en/Linguistic_relativity - Our language shapes our thought. This is true for spoken and programming languages. 2. You cannot properly understand a language…

> I would heartily recommend learning a new language.

I've installed a nice selection of languages tonight. Can anyone suggest sample projects to do as learning exercises? My ideas a) don't need the language, b) are too complex or c) involve CRUD, and I do far too much of that every day :)

TIA!

Re: Ask HN: I have a mental block designing software. Time to quit?

#70
post #69

What you're describing to me is you've built a very solid structure for reasoning about programs, but it is too rigid, and too focused. I would heartily recommend learning a new language. You need to shake things up a bit. Two reasons: 1. https://www.wikiwand.com/en/Linguistic_relativity - Our language shapes our thought. This is true for spoken and programming languages. 2. You cannot properly understand a language…

> I would heartily recommend learning a new language. I've installed a nice selection of languages tonight. Can anyone suggest sample projects to do as learning exercises? My ideas a) don't need the language, b) are too complex or c) involve CRUD, and I do far too much of that every day :) TIA!

Isnt your reason 'a' the point of doing something like that? To learn how to solve problems a different way?
Post reply on HN