You are correct in assuming that the creation of separate assemblies/projects to isolate your test code from your production code is the norm in .NET land. I really encourage the practice when mentoring people about unit testing because I don't want test code mixed in amongst my production code.
Generally speaking, I am extremely reluctant to test private/protected methods of my SUT. The great thing about TDD/UnitTesting is that you describe external behaviour and leave the implementation details flexible and "black boxed". You are then free to make as many refactorings as you feel are appropriate and as long as they do not break the external behaviours, the tests should not need to be changed.
If you are in some way tied to the implementation details (inheritance, access to privates/protected methods from within the production assembly), your tests will need to be refactored as frequently as the internal details of the class change.
Occasionally, you may have an internal class/method that you want to test. In this case, you can use the [assembly:InternalsVisibleTo("Test Assembly Name")] attribute in your production AssemblyInfo.cs file and allow your test assembly to see the internals of your production assembly.
InternalsVisibleToAttribute on MSDN
It should be noted that if you are new to .NET, internal is a different access qualifier than private and protected. An internal class is "public" within the assembly that houses it.
Hope this answers your questions.
Cheers,
Dave