Only the last one is tested (or that's how it seems) because you never stop the loop. So naturally, it continues till the end and complete is the last value set.
If you want to stop when setting it to false, then use break or even return since it seems you're done at that point.
And FYI, this is pretty pointless...
document.getElementById(''+i+'').id
It's the same as doing i or technically i.toString().
So rewriting your code, we could do this instead:
function checking(){
  for(var i = 1; i < 51; i++){
    if(i != document.getElementById(i).className) {
       document.getElementById('50').src = '../images/X.gif';
       complete = false;
       return;
    }  
  }
  document.getElementById('50').src = '../images/Y.jpg';
  complete = true;
}
Here I got rid of the else and put its code down below the loop. Now if there's a non-match, we set complete and return. If no non-matches are found, it goes to the code after the loop when the loop is done.
It does however seem like you're abusing variables. We don't know where complete is, but it seems like you should just return the desired boolean.
function checking(){
  for(var i = 1; i < 51; i++){
    if(i != document.getElementById(i).className) {
       document.getElementById('50').src = '../images/X.gif';
       return false;
    }  
  }
  document.getElementById('50').src = '../images/Y.jpg';
  return true;
}
var complete = checking();
Or a cleaner approach would be to create a single selector for all the IDs and use .every().
var sel = "#" + Array.apply(null, 50).map(function(_, i) { return i+1; }).join(",#");
var complete = [].every.call(document.querySelectorAll(sel), function(el) {
    return el.id === el.className;
});
document.getElementById('50').src = '../images/' + (complete ? 'Y.jpg' : 'X.jpg');