Basic Brainfuck interpreter (part 2)
In a word: dictionaries. 

You have a class that only has class attributes and lacks any methods; that could just be a dictionary:

lang = dict(
    step = 0,
    cell = [0] * 30000,
    test_cell = [0] * 30000,
    pos = 0,
    test_pos = 0,
    loop = False,
    loop_ret = 0
)


(Alternatively, if you really want attribute (foo.bar) rather than key (foo['bar']) access to the values, look into collections.namedtuple.)

You have a whole bunch of elifs; that could also be a dictionary (with some judiciously-named functions):

commands = {
    "+": increment_byte,
    "-": decrement_byte,
    ...
}


This makes your interpreter loop:

def interpreter():

    lang = dict(...)
    commands = {...}

    code_input = raw_input('Code: ')    
    steps = len(code_input)

    while lang['step'] &lt; steps:           
        command = code_input[lang['step']]
        if command in commands:
            commands[command](lang)    
        lang['step'] += 1


along with e.g.:

def increment_byte(lang):
    """Increment the byte at the data pointer."""
    val = lang['cell'][lang['pos']]
    lang['cell'][lang['pos']] = ((val + 1) % 256)


(Note use of % per @user50399's answer.)

This has two advantages:


very simple loop in interpreter; and
commands acts as a syntax guide (covering @Dagg's comment). 




You could also add some input validation:

def accept_input(lang):
    """Accept one char of input, storing its value in the byte at the data pointer."""
    while True:
        try:
            i = ord(raw_input("Enter char: "))
        except TypeError:
            pass
        else:
            if i in range(256):
                lang['cell'][lang['pos']] = i
                break
        print("Not a valid input.")


(Note switch to ord per @user50399's answer.)