diff --git a/pandas/core/frame.py b/pandas/core/frame.py
index 6dd9174028f18..d3dcae48dc6a0 100644
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -4978,7 +4978,7 @@ def _combine_match_columns(self, other, func, level=None):
         assert left.columns.equals(right.index)
         return ops.dispatch_to_series(left, right, func, axis="columns")
 
-    def _combine_const(self, other, func, errors='raise'):
+    def _combine_const(self, other, func):
         assert lib.is_scalar(other) or np.ndim(other) == 0
         return ops.dispatch_to_series(self, other, func)
 
diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py
index 2b2f9ca51ce12..5ee4d3407eb00 100644
--- a/pandas/core/indexes/range.py
+++ b/pandas/core/indexes/range.py
@@ -16,7 +16,8 @@
 from pandas.core.dtypes.common import (
     is_int64_dtype, is_integer, is_scalar, is_timedelta64_dtype
 )
-from pandas.core.dtypes.generic import ABCSeries, ABCTimedeltaIndex
+from pandas.core.dtypes.generic import (
+    ABCSeries, ABCTimedeltaIndex, ABCDataFrame)
 from pandas.core.indexes.base import Index, _index_shared_docs
 from pandas.core.indexes.numeric import Int64Index
 from pandas.util._decorators import Appender, cache_readonly
@@ -557,6 +558,9 @@ def __getitem__(self, key):
         return super_getitem(key)
 
     def __floordiv__(self, other):
+        if isinstance(other, (ABCSeries, ABCDataFrame)):
+            return NotImplemented
+
         if is_integer(other) and other != 0:
             if (len(self) == 0 or
                     self._start % other == 0 and
@@ -588,7 +592,7 @@ def _make_evaluate_binop(op, step=False):
             """
 
             def _evaluate_numeric_binop(self, other):
-                if isinstance(other, ABCSeries):
+                if isinstance(other, (ABCSeries, ABCDataFrame)):
                     return NotImplemented
                 elif isinstance(other, ABCTimedeltaIndex):
                     # Defer to TimedeltaIndex implementation
diff --git a/pandas/core/ops.py b/pandas/core/ops.py
index f29b4410fbf54..3c14446882315 100644
--- a/pandas/core/ops.py
+++ b/pandas/core/ops.py
@@ -45,6 +45,8 @@
     ABCIndex, ABCIndexClass,
     ABCSparseSeries, ABCSparseArray)
 
+from pandas.tseries.offsets import Tick
+
 
 # -----------------------------------------------------------------------------
 # Ops Wrapping Utilities
@@ -125,11 +127,16 @@ def maybe_upcast_for_op(obj):
     Be careful to call this *after* determining the `name` attribute to be
     attached to the result of the arithmetic operation.
     """
-    if type(obj) is datetime.timedelta:
+    if type(obj) is datetime.timedelta or isinstance(obj, Tick):
         # GH#22390  cast up to Timedelta to rely on Timedelta
         # implementation; otherwise operation against numeric-dtype
         # raises TypeError
         return pd.Timedelta(obj)
+    elif isinstance(obj, np.timedelta64):
+        # In particular non-nanosecond timedelta64 needs to be cast to
+        # nanoseconds, or else we get undesired behavior like
+        # np.timedelta64(3, 'D') / 2 == np.timedelta64(1, 'D')
+        return pd.Timedelta(obj)
     elif isinstance(obj, np.ndarray) and is_timedelta64_dtype(obj):
         # GH#22390 Unfortunately we need to special-case right-hand
         # timedelta64 dtypes because numpy casts integer dtypes to
@@ -1940,8 +1947,7 @@ def f(self, other):
 
             # straight boolean comparisons we want to allow all columns
             # (regardless of dtype to pass thru) See #4537 for discussion.
-            res = self._combine_const(other, func,
-                                      errors='ignore')
+            res = self._combine_const(other, func)
             return res.fillna(True).astype(bool)
 
     f.__name__ = op_name
diff --git a/pandas/core/sparse/frame.py b/pandas/core/sparse/frame.py
index e46df2b2bde70..56a5f4f49243f 100644
--- a/pandas/core/sparse/frame.py
+++ b/pandas/core/sparse/frame.py
@@ -642,7 +642,7 @@ def _combine_match_columns(self, other, func, level=None):
             new_data, index=self.index, columns=union,
             default_fill_value=self.default_fill_value).__finalize__(self)
 
-    def _combine_const(self, other, func, errors='raise'):
+    def _combine_const(self, other, func):
         return self._apply_columns(lambda x: func(x, other))
 
     def _reindex_index(self, index, method, copy, level, fill_value=np.nan,
diff --git a/pandas/tests/arithmetic/conftest.py b/pandas/tests/arithmetic/conftest.py
index b800b66e8edea..76b4022ce6f0a 100644
--- a/pandas/tests/arithmetic/conftest.py
+++ b/pandas/tests/arithmetic/conftest.py
@@ -84,7 +84,8 @@ def three_days(request):
                         pd.Timedelta(hours=2).to_pytimedelta(),
                         pd.Timedelta(seconds=2 * 3600),
                         np.timedelta64(2, 'h'),
-                        np.timedelta64(120, 'm')])
+                        np.timedelta64(120, 'm')],
+                ids=lambda x: str(x))
 def two_hours(request):
     """
     Several timedelta-like and DateOffset objects that each represent
@@ -141,31 +142,3 @@ def box(request):
     behavior with respect to arithmetic operations.
     """
     return request.param
-
-
-@pytest.fixture(params=[pd.Index,
-                        pd.Series,
-                        pytest.param(pd.DataFrame,
-                                     marks=pytest.mark.xfail(strict=True))],
-                ids=lambda x: x.__name__)
-def box_df_fail(request):
-    """
-    Fixture equivalent to `box` fixture but xfailing the DataFrame case.
-    """
-    return request.param
-
-
-@pytest.fixture(params=[
-    pd.Index,
-    pd.Series,
-    pytest.param(pd.DataFrame,
-                 marks=pytest.mark.xfail(reason="Tries to broadcast "
-                                                "incorrectly",
-                                         strict=True, raises=ValueError))
-], ids=lambda x: x.__name__)
-def box_df_broadcast_failure(request):
-    """
-    Fixture equivalent to `box` but with the common failing case where
-    the DataFrame operation tries to broadcast incorrectly.
-    """
-    return request.param
diff --git a/pandas/tests/arithmetic/test_datetime64.py b/pandas/tests/arithmetic/test_datetime64.py
index 71eba1e6901a1..24078f4578a0e 100644
--- a/pandas/tests/arithmetic/test_datetime64.py
+++ b/pandas/tests/arithmetic/test_datetime64.py
@@ -1366,14 +1366,12 @@ def test_sub_period(self, freq, box):
                                     operator.sub, ops.rsub])
     @pytest.mark.parametrize('pi_freq', ['D', 'W', 'Q', 'H'])
     @pytest.mark.parametrize('dti_freq', [None, 'D'])
-    def test_dti_sub_pi(self, dti_freq, pi_freq, op, box_df_broadcast_failure):
+    def test_dti_sub_pi(self, dti_freq, pi_freq, op, box):
         # GH#20049 subtracting PeriodIndex should raise TypeError
-        box = box_df_broadcast_failure
-
         dti = pd.DatetimeIndex(['2011-01-01', '2011-01-02'], freq=dti_freq)
         pi = dti.to_period(pi_freq)
 
-        dti = tm.box_expected(dti, box)
+        dti = tm.box_expected(dti, box, transpose=True)
         # TODO: Also box pi?
         with pytest.raises(TypeError):
             op(dti, pi)
diff --git a/pandas/tests/arithmetic/test_numeric.py b/pandas/tests/arithmetic/test_numeric.py
index 25845dd8b3151..b8b88630a4344 100644
--- a/pandas/tests/arithmetic/test_numeric.py
+++ b/pandas/tests/arithmetic/test_numeric.py
@@ -150,14 +150,6 @@ def test_numeric_arr_mul_tdscalar(self, scalar_td, numeric_idx, box):
     def test_numeric_arr_rdiv_tdscalar(self, three_days, numeric_idx, box):
         index = numeric_idx[1:3]
 
-        broken = (isinstance(three_days, np.timedelta64) and
-                  three_days.dtype != 'm8[ns]')
-        broken = broken or isinstance(three_days, pd.offsets.Tick)
-        if box is not pd.Index and broken:
-            # np.timedelta64(3, 'D') / 2 == np.timedelta64(1, 'D')
-            raise pytest.xfail("timedelta64 not converted to nanos; "
-                               "Tick division not implemented")
-
         expected = TimedeltaIndex(['3 Days', '36 Hours'])
 
         index = tm.box_expected(index, box)
diff --git a/pandas/tests/arithmetic/test_period.py b/pandas/tests/arithmetic/test_period.py
index 4ccebd4305b90..3d6a8cf499bf8 100644
--- a/pandas/tests/arithmetic/test_period.py
+++ b/pandas/tests/arithmetic/test_period.py
@@ -301,14 +301,12 @@ class TestPeriodIndexArithmetic(object):
     # PeriodIndex - other is defined for integers, timedelta-like others,
     #   and PeriodIndex (with matching freq)
 
-    def test_parr_add_iadd_parr_raises(self, box_df_broadcast_failure):
-        box = box_df_broadcast_failure
-
+    def test_parr_add_iadd_parr_raises(self, box):
         rng = pd.period_range('1/1/2000', freq='D', periods=5)
         other = pd.period_range('1/6/2000', freq='D', periods=5)
         # TODO: parametrize over boxes for other?
 
-        rng = tm.box_expected(rng, box)
+        rng = tm.box_expected(rng, box, transpose=True)
         # An earlier implementation of PeriodIndex addition performed
         # a set operation (union).  This has since been changed to
         # raise a TypeError. See GH#14164 and GH#13077 for historical
@@ -345,14 +343,12 @@ def test_pi_sub_pi_with_nat(self):
         expected = pd.Index([pd.NaT, 0 * off, 0 * off, 0 * off, 0 * off])
         tm.assert_index_equal(result, expected)
 
-    def test_parr_sub_pi_mismatched_freq(self, box_df_broadcast_failure):
-        box = box_df_broadcast_failure
-
+    def test_parr_sub_pi_mismatched_freq(self, box):
         rng = pd.period_range('1/1/2000', freq='D', periods=5)
         other = pd.period_range('1/6/2000', freq='H', periods=5)
         # TODO: parametrize over boxes for other?
 
-        rng = tm.box_expected(rng, box)
+        rng = tm.box_expected(rng, box, transpose=True)
         with pytest.raises(period.IncompatibleFrequency):
             rng - other
 
diff --git a/pandas/tests/arithmetic/test_timedelta64.py b/pandas/tests/arithmetic/test_timedelta64.py
index 56bef2fee2b41..af2e74dfb24c7 100644
--- a/pandas/tests/arithmetic/test_timedelta64.py
+++ b/pandas/tests/arithmetic/test_timedelta64.py
@@ -367,12 +367,8 @@ def test_td64arr_add_str_invalid(self, box):
                                     operator.sub, ops.rsub],
                              ids=lambda x: x.__name__)
     def test_td64arr_add_sub_float(self, box, op, other):
-        if box is pd.DataFrame and isinstance(other, np.ndarray):
-            pytest.xfail("Tries to broadcast, raising "
-                         "ValueError instead of TypeError")
-
         tdi = TimedeltaIndex(['-1 days', '-1 days'])
-        tdi = tm.box_expected(tdi, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
 
         with pytest.raises(TypeError):
             op(tdi, other)
@@ -393,15 +389,14 @@ def test_td64arr_sub_period(self, box, freq):
 
     @pytest.mark.parametrize('pi_freq', ['D', 'W', 'Q', 'H'])
     @pytest.mark.parametrize('tdi_freq', [None, 'H'])
-    def test_td64arr_sub_pi(self, box_df_broadcast_failure, tdi_freq, pi_freq):
+    def test_td64arr_sub_pi(self, box, tdi_freq, pi_freq):
         # GH#20049 subtracting PeriodIndex should raise TypeError
-        box = box_df_broadcast_failure
         tdi = TimedeltaIndex(['1 hours', '2 hours'], freq=tdi_freq)
         dti = Timestamp('2018-03-07 17:16:40') + tdi
         pi = dti.to_period(pi_freq)
 
         # TODO: parametrize over box for pi?
-        tdi = tm.box_expected(tdi, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
         with pytest.raises(TypeError):
             tdi - pi
 
@@ -455,16 +450,14 @@ def test_td64arr_add_sub_timestamp(self, box):
         with pytest.raises(TypeError):
             tdser - ts
 
-    def test_tdi_sub_dt64_array(self, box_df_broadcast_failure):
-        box = box_df_broadcast_failure
-
+    def test_tdi_sub_dt64_array(self, box):
         dti = pd.date_range('2016-01-01', periods=3)
         tdi = dti - dti.shift(1)
         dtarr = dti.values
         expected = pd.DatetimeIndex(dtarr) - tdi
 
-        tdi = tm.box_expected(tdi, box)
-        expected = tm.box_expected(expected, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
         with pytest.raises(TypeError):
             tdi - dtarr
@@ -473,16 +466,14 @@ def test_tdi_sub_dt64_array(self, box_df_broadcast_failure):
         result = dtarr - tdi
         tm.assert_equal(result, expected)
 
-    def test_tdi_add_dt64_array(self, box_df_broadcast_failure):
-        box = box_df_broadcast_failure
-
+    def test_tdi_add_dt64_array(self, box):
         dti = pd.date_range('2016-01-01', periods=3)
         tdi = dti - dti.shift(1)
         dtarr = dti.values
         expected = pd.DatetimeIndex(dtarr) + tdi
 
-        tdi = tm.box_expected(tdi, box)
-        expected = tm.box_expected(expected, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
         result = tdi + dtarr
         tm.assert_equal(result, expected)
@@ -506,11 +497,10 @@ def test_td64arr_add_int_series_invalid(self, box, tdser):
         with pytest.raises(err):
             int_ser - tdser
 
-    def test_td64arr_add_intlike(self, box_df_broadcast_failure):
+    def test_td64arr_add_intlike(self, box):
         # GH#19123
-        box = box_df_broadcast_failure
         tdi = TimedeltaIndex(['59 days', '59 days', 'NaT'])
-        ser = tm.box_expected(tdi, box)
+        ser = tm.box_expected(tdi, box, transpose=True)
         err = TypeError if box is not pd.Index else NullFrequencyError
 
         other = Series([20, 30, 40], dtype='uint8')
@@ -562,10 +552,7 @@ def test_td64arr_add_sub_numeric_scalar_invalid(self, box, scalar, tdser):
         # TODO: Add DataFrame in here?
     ], ids=lambda x: type(x).__name__)
     def test_td64arr_add_sub_numeric_arr_invalid(self, box, vec, dtype, tdser):
-        if box is pd.DataFrame and not isinstance(vec, Series):
-            raise pytest.xfail(reason="Tries to broadcast incorrectly")
-
-        tdser = tm.box_expected(tdser, box)
+        tdser = tm.box_expected(tdser, box, transpose=True)
         err = TypeError
         if box is pd.Index and not dtype.startswith('float'):
             err = NullFrequencyError
@@ -637,32 +624,28 @@ def test_timedelta64_operations_with_timedeltas(self):
         # roundtrip
         tm.assert_series_equal(result + td2, td1)
 
-    def test_td64arr_add_td64_array(self, box_df_broadcast_failure):
-        box = box_df_broadcast_failure
-
+    def test_td64arr_add_td64_array(self, box):
         dti = pd.date_range('2016-01-01', periods=3)
         tdi = dti - dti.shift(1)
         tdarr = tdi.values
 
         expected = 2 * tdi
-        tdi = tm.box_expected(tdi, box)
-        expected = tm.box_expected(expected, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
         result = tdi + tdarr
         tm.assert_equal(result, expected)
         result = tdarr + tdi
         tm.assert_equal(result, expected)
 
-    def test_td64arr_sub_td64_array(self, box_df_broadcast_failure):
-        box = box_df_broadcast_failure
-
+    def test_td64arr_sub_td64_array(self, box):
         dti = pd.date_range('2016-01-01', periods=3)
         tdi = dti - dti.shift(1)
         tdarr = tdi.values
 
         expected = 0 * tdi
-        tdi = tm.box_expected(tdi, box)
-        expected = tm.box_expected(expected, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
         result = tdi - tdarr
         tm.assert_equal(result, expected)
@@ -673,17 +656,19 @@ def test_td64arr_sub_td64_array(self, box_df_broadcast_failure):
     @pytest.mark.parametrize('names', [(None, None, None),
                                        ('Egon', 'Venkman', None),
                                        ('NCC1701D', 'NCC1701D', 'NCC1701D')])
-    def test_td64arr_add_sub_tdi(self, box_df_broadcast_failure, names):
+    def test_td64arr_add_sub_tdi(self, box, names):
         # GH#17250 make sure result dtype is correct
         # GH#19043 make sure names are propagated correctly
-        box = box_df_broadcast_failure
+        if box is pd.DataFrame and names[0] != names[1]:
+            return
+
         tdi = TimedeltaIndex(['0 days', '1 day'], name=names[0])
         ser = Series([Timedelta(hours=3), Timedelta(hours=4)], name=names[1])
         expected = Series([Timedelta(hours=3), Timedelta(days=1, hours=4)],
                           name=names[2])
 
-        ser = tm.box_expected(ser, box)
-        expected = tm.box_expected(expected, box)
+        ser = tm.box_expected(ser, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
         result = tdi + ser
         tm.assert_equal(result, expected)
@@ -701,7 +686,7 @@ def test_td64arr_add_sub_tdi(self, box_df_broadcast_failure, names):
 
         expected = Series([Timedelta(hours=-3), Timedelta(days=1, hours=-4)],
                           name=names[2])
-        expected = tm.box_expected(expected, box)
+        expected = tm.box_expected(expected, box, transpose=True)
 
         result = tdi - ser
         tm.assert_equal(result, expected)
@@ -789,9 +774,11 @@ def test_timedelta64_operations_with_DateOffset(self):
     @pytest.mark.parametrize('names', [(None, None, None),
                                        ('foo', 'bar', None),
                                        ('foo', 'foo', 'foo')])
-    def test_td64arr_add_offset_index(self, names, box_df_broadcast_failure):
+    def test_td64arr_add_offset_index(self, names, box):
         # GH#18849, GH#19744
-        box = box_df_broadcast_failure
+        if box is pd.DataFrame and names[0] != names[1]:
+            return
+
         tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'],
                              name=names[0])
         other = pd.Index([pd.offsets.Hour(n=1), pd.offsets.Minute(n=-2)],
@@ -799,45 +786,48 @@ def test_td64arr_add_offset_index(self, names, box_df_broadcast_failure):
 
         expected = TimedeltaIndex([tdi[n] + other[n] for n in range(len(tdi))],
                                   freq='infer', name=names[2])
-        tdi = tm.box_expected(tdi, box)
-        expected = tm.box_expected(expected, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
-        with tm.assert_produces_warning(PerformanceWarning):
+        exwarning = PerformanceWarning if box is not pd.DataFrame else None
+        with tm.assert_produces_warning(exwarning):
             res = tdi + other
         tm.assert_equal(res, expected)
 
-        with tm.assert_produces_warning(PerformanceWarning):
+        with tm.assert_produces_warning(exwarning):
             res2 = other + tdi
         tm.assert_equal(res2, expected)
 
     # TODO: combine with test_td64arr_add_offset_index by parametrizing
     # over second box?
-    def test_td64arr_add_offset_array(self, box_df_broadcast_failure):
+    def test_td64arr_add_offset_array(self, box):
         # GH#18849
-        box = box_df_broadcast_failure
         tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'])
         other = np.array([pd.offsets.Hour(n=1), pd.offsets.Minute(n=-2)])
 
         expected = TimedeltaIndex([tdi[n] + other[n] for n in range(len(tdi))],
                                   freq='infer')
 
-        tdi = tm.box_expected(tdi, box)
-        expected = tm.box_expected(expected, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
-        with tm.assert_produces_warning(PerformanceWarning):
+        exwarning = PerformanceWarning if box is not pd.DataFrame else None
+        with tm.assert_produces_warning(exwarning):
             res = tdi + other
         tm.assert_equal(res, expected)
 
-        with tm.assert_produces_warning(PerformanceWarning):
+        with tm.assert_produces_warning(exwarning):
             res2 = other + tdi
         tm.assert_equal(res2, expected)
 
     @pytest.mark.parametrize('names', [(None, None, None),
                                        ('foo', 'bar', None),
                                        ('foo', 'foo', 'foo')])
-    def test_td64arr_sub_offset_index(self, names, box_df_broadcast_failure):
+    def test_td64arr_sub_offset_index(self, names, box):
         # GH#18824, GH#19744
-        box = box_df_broadcast_failure
+        if box is pd.DataFrame and names[0] != names[1]:
+            return
+
         tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'],
                              name=names[0])
         other = pd.Index([pd.offsets.Hour(n=1), pd.offsets.Minute(n=-2)],
@@ -846,36 +836,40 @@ def test_td64arr_sub_offset_index(self, names, box_df_broadcast_failure):
         expected = TimedeltaIndex([tdi[n] - other[n] for n in range(len(tdi))],
                                   freq='infer', name=names[2])
 
-        tdi = tm.box_expected(tdi, box)
-        expected = tm.box_expected(expected, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
-        with tm.assert_produces_warning(PerformanceWarning):
+        exwarning = PerformanceWarning if box is not pd.DataFrame else None
+        with tm.assert_produces_warning(exwarning):
             res = tdi - other
         tm.assert_equal(res, expected)
 
-    def test_td64arr_sub_offset_array(self, box_df_broadcast_failure):
+    def test_td64arr_sub_offset_array(self, box):
         # GH#18824
-        box = box_df_broadcast_failure
         tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'])
         other = np.array([pd.offsets.Hour(n=1), pd.offsets.Minute(n=-2)])
 
         expected = TimedeltaIndex([tdi[n] - other[n] for n in range(len(tdi))],
                                   freq='infer')
 
-        tdi = tm.box_expected(tdi, box)
-        expected = tm.box_expected(expected, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
-        with tm.assert_produces_warning(PerformanceWarning):
+        exwarning = PerformanceWarning if box is not pd.DataFrame else None
+        with tm.assert_produces_warning(exwarning):
             res = tdi - other
         tm.assert_equal(res, expected)
 
     @pytest.mark.parametrize('names', [(None, None, None),
                                        ('foo', 'bar', None),
                                        ('foo', 'foo', 'foo')])
-    def test_td64arr_with_offset_series(self, names, box_df_fail):
+    def test_td64arr_with_offset_series(self, names, box):
         # GH#18849
-        box = box_df_fail
+        if box is pd.DataFrame and names[0] != names[1]:
+            return
+
         box2 = Series if box is pd.Index else box
+        exwarning = PerformanceWarning if box is not pd.DataFrame else None
 
         tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'],
                              name=names[0])
@@ -884,34 +878,31 @@ def test_td64arr_with_offset_series(self, names, box_df_fail):
 
         expected_add = Series([tdi[n] + other[n] for n in range(len(tdi))],
                               name=names[2])
-        tdi = tm.box_expected(tdi, box)
-        expected_add = tm.box_expected(expected_add, box2)
+        expected_sub = Series([tdi[n] - other[n] for n in range(len(tdi))],
+                              name=names[2])
 
-        with tm.assert_produces_warning(PerformanceWarning):
+        tdi = tm.box_expected(tdi, box, transpose=True)
+        expected_add = tm.box_expected(expected_add, box2, transpose=True)
+
+        with tm.assert_produces_warning(exwarning):
             res = tdi + other
         tm.assert_equal(res, expected_add)
 
-        with tm.assert_produces_warning(PerformanceWarning):
+        with tm.assert_produces_warning(exwarning):
             res2 = other + tdi
         tm.assert_equal(res2, expected_add)
 
-        # TODO: separate/parametrize add/sub test?
-        expected_sub = Series([tdi[n] - other[n] for n in range(len(tdi))],
-                              name=names[2])
-        expected_sub = tm.box_expected(expected_sub, box2)
+        expected_sub = tm.box_expected(expected_sub, box2, transpose=True)
 
-        with tm.assert_produces_warning(PerformanceWarning):
+        with tm.assert_produces_warning(exwarning):
             res3 = tdi - other
         tm.assert_equal(res3, expected_sub)
 
     @pytest.mark.parametrize('obox', [np.array, pd.Index, pd.Series])
     def test_td64arr_addsub_anchored_offset_arraylike(self, obox, box):
         # GH#18824
-        if box is pd.DataFrame and obox is not pd.Series:
-            raise pytest.xfail(reason="Attempts to broadcast incorrectly")
-
         tdi = TimedeltaIndex(['1 days 00:00:00', '3 days 04:00:00'])
-        tdi = tm.box_expected(tdi, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
 
         anchored = obox([pd.offsets.MonthEnd(), pd.offsets.Day(n=2)])
 
@@ -987,40 +978,37 @@ def test_tdi_mul_int_array_zerodim(self, box):
         result = idx * np.array(5, dtype='int64')
         tm.assert_equal(result, expected)
 
-    def test_tdi_mul_int_array(self, box_df_broadcast_failure):
-        box = box_df_broadcast_failure
+    def test_tdi_mul_int_array(self, box):
         rng5 = np.arange(5, dtype='int64')
         idx = TimedeltaIndex(rng5)
         expected = TimedeltaIndex(rng5 ** 2)
 
-        idx = tm.box_expected(idx, box)
-        expected = tm.box_expected(expected, box)
+        idx = tm.box_expected(idx, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
         result = idx * rng5
         tm.assert_equal(result, expected)
 
-    def test_tdi_mul_int_series(self, box_df_fail):
-        box = box_df_fail
+    def test_tdi_mul_int_series(self, box):
         idx = TimedeltaIndex(np.arange(5, dtype='int64'))
         expected = TimedeltaIndex(np.arange(5, dtype='int64') ** 2)
 
-        idx = tm.box_expected(idx, box)
+        idx = tm.box_expected(idx, box, transpose=True)
 
         box2 = pd.Series if box is pd.Index else box
-        expected = tm.box_expected(expected, box2)
+        expected = tm.box_expected(expected, box2, transpose=True)
 
         result = idx * pd.Series(np.arange(5, dtype='int64'))
         tm.assert_equal(result, expected)
 
-    def test_tdi_mul_float_series(self, box_df_fail):
-        box = box_df_fail
+    def test_tdi_mul_float_series(self, box):
         idx = TimedeltaIndex(np.arange(5, dtype='int64'))
-        idx = tm.box_expected(idx, box)
+        idx = tm.box_expected(idx, box, transpose=True)
 
         rng5f = np.arange(5, dtype='float64')
         expected = TimedeltaIndex(rng5f * (rng5f + 0.1))
         box2 = pd.Series if box is pd.Index else box
-        expected = tm.box_expected(expected, box2)
+        expected = tm.box_expected(expected, box2, transpose=True)
 
         result = idx * Series(rng5f + 0.1)
         tm.assert_equal(result, expected)
@@ -1033,16 +1021,12 @@ def test_tdi_mul_float_series(self, box_df_fail):
         pd.Float64Index(range(1, 11)),
         pd.RangeIndex(1, 11)
     ], ids=lambda x: type(x).__name__)
-    def test_tdi_rmul_arraylike(self, other, box_df_fail):
-        # RangeIndex fails to return NotImplemented, for others
-        # DataFrame tries to broadcast incorrectly
-        box = box_df_fail
-
+    def test_tdi_rmul_arraylike(self, other, box):
         tdi = TimedeltaIndex(['1 Day'] * 10)
         expected = timedelta_range('1 days', '10 days')
 
-        tdi = tm.box_expected(tdi, box)
-        expected = tm.box_expected(expected, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
+        expected = tm.box_expected(expected, box, transpose=True)
 
         result = other * tdi
         tm.assert_equal(result, expected)
@@ -1249,32 +1233,22 @@ def test_td64arr_div_numeric_scalar(self, box, two, tdser):
                                         Series([20, 30, 40])],
                              ids=lambda x: type(x).__name__)
     @pytest.mark.parametrize('op', [operator.mul, ops.rmul])
-    def test_td64arr_rmul_numeric_array(self, op, box_df_fail,
-                                        vector, dtype, tdser):
+    def test_td64arr_rmul_numeric_array(self, op, box, vector, dtype, tdser):
         # GH#4521
         # divide/multiply by integers
-        box = box_df_fail  # broadcasts incorrectly but doesn't raise
         vector = vector.astype(dtype)
 
         expected = Series(['1180 Days', '1770 Days', 'NaT'],
                           dtype='timedelta64[ns]')
 
-        tdser = tm.box_expected(tdser, box)
+        tdser = tm.box_expected(tdser, box, transpose=True)
         # TODO: Make this up-casting more systematic?
-        box = Series if (box is pd.Index and type(vector) is Series) else box
-        expected = tm.box_expected(expected, box)
+        box2 = Series if (box is pd.Index and type(vector) is Series) else box
+        expected = tm.box_expected(expected, box2, transpose=True)
 
         result = op(vector, tdser)
         tm.assert_equal(result, expected)
 
-    @pytest.mark.parametrize('box', [
-        pd.Index,
-        Series,
-        pytest.param(pd.DataFrame,
-                     marks=pytest.mark.xfail(reason="broadcasts along "
-                                                    "wrong axis",
-                                             strict=True))
-    ], ids=lambda x: x.__name__)
     @pytest.mark.parametrize('dtype', ['int64', 'int32', 'int16',
                                        'uint64', 'uint32', 'uint16', 'uint8',
                                        'float64', 'float32', 'float16'])
@@ -1289,9 +1263,9 @@ def test_td64arr_div_numeric_array(self, box, vector, dtype, tdser):
         expected = Series(['2.95D', '1D 23H 12m', 'NaT'],
                           dtype='timedelta64[ns]')
 
-        tdser = tm.box_expected(tdser, box)
+        tdser = tm.box_expected(tdser, box, transpose=True)
         box = Series if (box is pd.Index and type(vector) is Series) else box
-        expected = tm.box_expected(expected, box)
+        expected = tm.box_expected(expected, box, transpose=True)
 
         result = tdser / vector
         tm.assert_equal(result, expected)
@@ -1302,9 +1276,11 @@ def test_td64arr_div_numeric_array(self, box, vector, dtype, tdser):
     @pytest.mark.parametrize('names', [(None, None, None),
                                        ('Egon', 'Venkman', None),
                                        ('NCC1701D', 'NCC1701D', 'NCC1701D')])
-    def test_td64arr_mul_int_series(self, box_df_fail, names):
+    def test_td64arr_mul_int_series(self, box, names):
         # GH#19042 test for correct name attachment
-        box = box_df_fail  # broadcasts along wrong axis, but doesn't raise
+        if box is pd.DataFrame and names[0] != names[1]:
+            return
+
         tdi = TimedeltaIndex(['0days', '1day', '2days', '3days', '4days'],
                              name=names[0])
         # TODO: Should we be parametrizing over types for `ser` too?
@@ -1314,15 +1290,14 @@ def test_td64arr_mul_int_series(self, box_df_fail, names):
                           dtype='timedelta64[ns]',
                           name=names[2])
 
-        tdi = tm.box_expected(tdi, box)
+        tdi = tm.box_expected(tdi, box, transpose=True)
         box = Series if (box is pd.Index and type(ser) is Series) else box
-        expected = tm.box_expected(expected, box)
+        expected = tm.box_expected(expected, box, transpose=True)
 
         result = ser * tdi
         tm.assert_equal(result, expected)
 
-        # The direct operation tdi * ser still needs to be fixed.
-        result = ser.__rmul__(tdi)
+        result = tdi * ser
         tm.assert_equal(result, expected)
 
     # TODO: Should we be parametrizing over types for `ser` too?
diff --git a/pandas/tests/indexes/test_range.py b/pandas/tests/indexes/test_range.py
index 0e47fcd52f625..fd2df39b1e7e7 100644
--- a/pandas/tests/indexes/test_range.py
+++ b/pandas/tests/indexes/test_range.py
@@ -189,6 +189,25 @@ def test_constructor_name(self):
         assert copy.name == 'copy'
         assert new.name == 'new'
 
+    # TODO: mod, divmod?
+    @pytest.mark.parametrize('op', [operator.add, operator.sub,
+                                    operator.mul, operator.floordiv,
+                                    operator.truediv, operator.pow])
+    def test_arithmetic_with_frame_or_series(self, op):
+        # check that we return NotImplemented when operating with Series
+        # or DataFrame
+        index = pd.RangeIndex(5)
+        other = pd.Series(np.random.randn(5))
+
+        expected = op(pd.Series(index), other)
+        result = op(index, other)
+        tm.assert_series_equal(result, expected)
+
+        other = pd.DataFrame(np.random.randn(2, 5))
+        expected = op(pd.DataFrame([index, index]), other)
+        result = op(index, other)
+        tm.assert_frame_equal(result, expected)
+
     def test_numeric_compat2(self):
         # validate that we are handling the RangeIndex overrides to numeric ops
         # and returning RangeIndex where possible
diff --git a/pandas/tests/internals/test_internals.py b/pandas/tests/internals/test_internals.py
index cdf35ea96588a..b327b158adc24 100644
--- a/pandas/tests/internals/test_internals.py
+++ b/pandas/tests/internals/test_internals.py
@@ -1243,7 +1243,6 @@ def test_binop_other(self, op, value, dtype):
                    (operator.mul, '<M8[ns]'),
                    (operator.add, '<M8[ns]'),
                    (operator.pow, '<m8[ns]'),
-                   (operator.mod, '<m8[ns]'),
                    (operator.mul, '<m8[ns]')}
 
         if (op, dtype) in invalid:
diff --git a/pandas/util/testing.py b/pandas/util/testing.py
index a93487a21696d..2bce7ef0a1f0a 100644
--- a/pandas/util/testing.py
+++ b/pandas/util/testing.py
@@ -1551,7 +1551,7 @@ def assert_equal(left, right, **kwargs):
         raise NotImplementedError(type(left))
 
 
-def box_expected(expected, box_cls):
+def box_expected(expected, box_cls, transpose=False):
     """
     Helper function to wrap the expected output of a test in a given box_class.
 
@@ -1559,6 +1559,8 @@ def box_expected(expected, box_cls):
     ----------
     expected : np.ndarray, Index, Series
     box_cls : {Index, Series, DataFrame}
+    transpose : bool
+        whether to transpose the result; only relevant for DataFrame
 
     Returns
     -------
@@ -1570,6 +1572,11 @@ def box_expected(expected, box_cls):
         expected = pd.Series(expected)
     elif box_cls is pd.DataFrame:
         expected = pd.Series(expected).to_frame()
+        if transpose:
+            # For tests in which a DataFrame operates with a 1-dimensional
+            # array-like other, broadcasting conventions require us to
+            # transpose both the DataFrame operand and the expected result.
+            expected = expected.T
     elif box_cls is np.ndarray:
         expected = np.array(expected)
     else: