Testbenches are Verilog code that provides a set of stimuli that are portable across different simulators. It must be either a simple set of stimuli (clock, reset, some simple inputs behavior) or a strong well defined test with randomization, logging, protocol control, checks etc.
In general a good testbench must be based on a module's specification, and must work with the designer's rtl. Only simple tests may be written in such a way - initial checks of compilation, elaboration and non-algorithmic runtime errors.
The tested module must be instantiated into the top level testbench module. Usually, this instance is called DUT (or dut) - Design Under Test. The testbench's module doesn't have to have any ports so it's declaration is something like module tb;
The example of a one of simplest testbenches:
module tb();
reg clk = 1'b0;
always #10 clk = ~clk;
reg signed [7:0] a = -128, b = -128;
wire signed [8:0] c;
always @(posedge clk) begin
a <= a + 1;
if (a == 127) b <= b + 1;
end
subtractor dut (a, b, c);
endmodule