user9863: I'm writing a chess engine, and I'm testing that the move generator is working correctly using a perft() function.  In perft position 2 my engine appears to be 90 moves short at ply 2.  How do authors of other engines then debug their engines?  Is there a full list of perft moves available online somewhere?
The obvious issue with using an established engine to enumerate the moves is if there's a bug in the move generation function in the established engine.

user825: 
The obvious issue with using an established engine to enumerate the moves is if there's a bug in the move generation function in the established engine.

Stockfish is always perfectly correct.
Goto https://github.com/official-stockfish/Stockfish/blob/master/src/search.cpp, add a std::cout in perft(). Recompile, and then run perft. Redirect your results to a text file.
Sort the results with: sort SFMoves.txt > SortedSFMoves.txt.
Similarly, repeat for your generator, sort it and then compare with Stockfish.
Common mistakes:

En-passpant
Underpromotion
Promote with a capture

Please check the special cases in your code.

user27991: I know this is an old question, but I strongly recommend the use of the perftree program. It compares the results of your perft function with the one implemented by Stockfish. This helped me a lot to debug my move generator.
For instance, if you run perft(6) and find out that, e.g., the number of moves from a2a3 is larger/lower than it should be, you update the position by doing such move, and then you run perft(5). You repeat this until you reach depth 1, where you can find out what kind of moves you are allowing (pseudolegal) or missing.

9863: <p>I'm writing a chess engine, and I'm testing that the move generator is working correctly using a perft() function.  In perft position 2 my engine appears to be 90 moves short at ply 2.  How do authors of other engines then debug their engines?  Is there a full list of perft moves available online somewhere?</p>

<p>The obvious issue with using an established engine to enumerate the moves is if there's a bug in the move generation function in the established engine.</p>
 825: <blockquote>
  <p>The obvious issue with using an established engine to enumerate the moves is if there's a bug in the move generation function in the established engine.</p>
</blockquote>

<p>Stockfish is always perfectly correct.</p>

<p>Goto <a href="https://github.com/official-stockfish/Stockfish/blob/master/src/search.cpp" rel="nofollow noreferrer">https://github.com/official-stockfish/Stockfish/blob/master/src/search.cpp</a>, add a <code>std::cout</code> in <code>perft()</code>. Recompile, and then run perft. Redirect your results to a text file.</p>

<p>Sort the results with: <code>sort SFMoves.txt &gt; SortedSFMoves.txt</code>.</p>

<p>Similarly, repeat for your generator, sort it and then compare with Stockfish.</p>

<p>Common mistakes:</p>

<ul>
<li>En-passpant</li>
<li>Underpromotion</li>
<li>Promote with a capture</li>
</ul>

<p>Please check the special cases in your code.</p>
 27991: <p>I know this is an old question, but I strongly recommend the use of the <a href="https://github.com/agausmann/perftree" rel="nofollow noreferrer">perftree</a> program. It compares the results of your <code>perft</code> function with the one implemented by Stockfish. This helped me a lot to debug my move generator.</p>
<p>For instance, if you run <code>perft(6)</code> and find out that, e.g., the number of moves from <strong>a2a3</strong> is larger/lower than it should be, you update the position by doing such move, and then you run <code>perft(5)</code>. You repeat this until you reach depth 1, where you can find out what kind of moves you are allowing (pseudolegal) or missing.</p>
