Implement Conway's Game of Life in your preferred programming language, ensuring clean code structure and comprehensive test coverage.
Implement advance_game_of_life(board, steps), where board is a rectangular list of 0 and 1 integers. Return a new board after the requested number of generations; do not mutate the input. Cells outside the board are always dead. For each generation, a live cell survives with two or three neighbors, and a dead cell becomes live with exactly three neighbors.
steps is a nonnegative integer. Return a board with the same dimensions.
def advance_game_of_life(board, steps):