There's no advantage in using directly \@testopt, in my opinion. The question you refer to has
\def\collecttikzpicture{\@testopt\@collecttikzpicture{}}
\def\@collecttikzpicture[#1]{%
\global\setbox\tempbox=\hbox\bgroup\begin{tikzpicture}[#1]%
}
that is functionally equivalent to
\newcommand\collecttikzpicture[1][]{%
\global\setbox\tempbox=\hbox\bgroup\begin{tikzpicture}[#1]%
}
and has the advantage of being robust, that is it eventually expands to itself when used in moving arguments, which is not the case for the former definition.
With the latter definition, the expansion of \collecttikzpicture will be
\@protected@testopt \collecttikzpicture \\collecttikzpicture {}
where the third token is a peculiar control sequence with a backslash in its name, which has the same office as \@collecttikzpicture in the previous definition. So you don't even have to worry about defining an auxiliary control sequence for the real action, because \newcommand will take care of that automatically. When \@protected@testopt is expanded, it uses \@testopt, so \kernel@ifnextchar (and not \@ifnextchar).
Defining a command having mandatory arguments with \@testopt is really easy:
\def\foo{\@testopt\@foo{DEFAULT}}
\def\@foo[#1]#2#3{Something with #1, #2, #3}
Let's see why following the expansion of \foo{X}{Y} and \foo[A]{X}{Y}. Here's the first one:
\foo{X}{Y}
\@testopt\@foo{DEFAULT}{X}{Y}
\kernel@ifnextchar [{\@foo}{\@foo[{DEFAULT}]}{X}{Y}
\@foo[{DEFAULT}]{X}{Y}
Something with DEFAULT, X, Y
Here's the second:
\foo[A]{X}{Y}
\@testopt\@foo{DEFAULT}[A]{X}{Y}
\kernel@ifnextchar [{\@foo}{\@foo[{DEFAULT}]}[A]{X}{Y}
\@foo[A]{X}{Y}
Something with A, X, Y
But, of course,
\newcommand{\foo}[3][1]{Something with #1, #2 and #3}
is easier and robust.
{}arguments (I mean is there any difference in usage?) – yo' Jun 13 '12 at 07:20