Unit testing and full-service testing
There's nothing quite like making a change, running a battery of tests on it, and having a certain level of confidence that your change didn't break something else.
Your confidence is only as good as your test coverage, so learning how to write good test cases is key -- code coverage, making sure that you test all the decision points in your code (not just lines of code, but follow each decision through every if
, case
, while
, etc).
Nunit is probably a fine unit-testing tool to learn for .Net. (.Net is pretty foreign to me, but ?unit is a well-known testing design, so learning one framework should make transitioning to other frameworks less painful than learning the first one.)
You might want to start implementing Nunit tests for your own hobby projects first -- I'm guessing your employer doesn't have much flexibility for on-the-job-learning. But you'll have to gage that.
Source-code control
Keeping everything except throw-away code in source control is key to maintaining sanity. There's no reason for keeping four or five versions of a program's source in one directory, or wondering which pieces of code you've copied-pasted from a 'fixed' version to one you're trying to extend.
When you check in changes, try to check in just functionally-related changes at a time. You might need to revert changes later, and if a changeset actually includes two, three, or more unrelated fixes or features (or worse, both fixes and features) then picking specific pieces back out later can be very difficult. Also, try to write your commit messages as if someone else will read them. Someone else might. And you count as 'someone else' in six months time.
It's easy to reap big benefits from source control quickly, and it is easy to build extensively on it -- the Linux kernel community tries very hard to maintain an it always builds state with every commit, so that people can use tools such as git bisect
to help find changes that broke specific features. If it doesn't compile, those tools are much less useful. But this can be something you strive for, you don't have to be perfect right away. Please promise me you won't use SourceSafe -- at least with piles of files in directories, you know where you stand. Git, Subversion, Mercurial, BitKeeper, Darcs, Arch, all are significantly better than SourceSafe.
In general
I'd also like to suggest developing a serious case of paranoia and skepticism. Assume your users are trying to break your software. Imagine them stuffing completely incorrect inputs into every input mechanism in your software, and figure out how to fail gracefully.