I am wondering should I write unit test for everything. There are some classes is very difficult to write unit test. For example, I am writing some program for handling audi
Code that capture and replay audio cannot be unit-tested (albeit you could test that the capture method returns an error when called when the class isn't successfully bound to a resource).
However, unless you simply write the captured sound to disk the code that invokes your capture and play classes certainly can.
Two pieces of advice:
The short answer is, No, but then that goes for everything in programming when you ask, "Should I X for everything?"
The longer answer is you should at least consider it, which you are doing. Why can't you mock input into a sound recording class? Why not have the class bypass recording from a microphone to load audio from a file and have the output go to a file instead of a speaker. The test could compare the output result to the known correct result.
For more on the philosophical side see this.
To answer your specific question, use a loopback cable. Connect the speaker out to the mic in. Write a test that renders to the speaker and captures from the mic and verifies that the same thing you played was captured. My suggestion is to use a simple sine tone so that an FFT can tell you if you captured back the same thing.
The answer to the more general question is yes, you should unit test everything you can. Doing so creates a legacy for later so changes down the road can be done with peace of mind. It ensures that your code works as expected. It also documents the intended usage of the interfaces. Finally, it forces better coding style. Usually something which is hard to unit test is also poorly designed. Writing for testability means writing for better design.
One rule I use for deciding whether to develop unit tests: if your class (or whatever unit) is going to be released "into the wild", then you should definitely consider writing unit tests.
By "in the wild", I mean: once your code is going to be in a situation where you cannot predict or control how things will interact with it. So classes exposed through an API, or classes exposed to user input should probably be unit tested.
Personally, I think that writing unit tests for everything is likely to be a waste of your time. It really is a complex issue where you need to consider:
Then there's always:
As for difficult classes, maybe do some reading about fuzz testing.
You might want to check my series "Testing the Impossible" in my blog for some ideas how to test.
In your case, I suggest to follow the idea of Steve Rowe to write a test which sets up the speaker and microphone and use a loopback cable to test the hardware setup code plus the API which allows to emit data via the speaker and read data from the mic.
This is a unit test but not an automated one. Move it into an independent test suite which doesn't run with the other automatic tests. If you want to automate it, set up a second PC with the correct configuration (plus the loopback cable) and run the test remotely.
After that, you are sure that the hardware setup works, you can send and you can receive audio. This allows you to test the data processing classes independent of the hardware. Use mockups to simulate the speaker and mic.
Use unit testing where it makes sense - don't aim for 100% coverage. The main guideline is to think rather than applying either dogma or laziness.
Having said that: If you have classes which are naturally hard to test, try to reduce how much they have to do. Isolate the untestable code and separate its API into an interface. Then test the logic which uses that API against a mock or stub.