TST: make assertion messages more understandable
State: closed

Closes #10373. Also, this is based on #10500 and #10501.

The fix also did some refactoring related to `assert_index_equal`. Added `check_exact` and `check_less_precise`, and moved logics from `assert_series_equal` and `assert_frame_equal` for cleanups.

Followings are the list of tested and what the output looks like
## Index
- Shape (size)
- Dtype
- Values
- Metadata 

```
tm.assert_index_equal(pd.Index([1, 2, 3]), pd.Index([1, 2, 3, 4]))
# AssertionError: Index are different
# 
# Index length are different
# [left]:  3, Int64Index([1, 2, 3], dtype='int64')
# [right]: 4, Int64Index([1, 2, 3, 4], dtype='int64')

tm.assert_index_equal(pd.Index([1, 2, 3]), pd.Index([1, 2, 5]))
# AssertionError: Index are different
# 
# Index values are different (33.33333 %)
# [left]:  Int64Index([1, 2, 3], dtype='int64')
# [right]: Int64Index([1, 2, 5], dtype='int64')

tm.assert_index_equal(pd.Index([1, 2, 3]), pd.Index([1, 2, 3], name='x'))
# AssertionError: Index are different
# 
# Attribute "names" are different
# [left]:  [None]
# [right]: [u'x']
```
## Series
- Shape (size)
- Dtype 
- Index (same as above)
- Values
- Metadata (same as above)

```
tm.assert_series_equal(pd.Series([1, 2]), pd.Series([1, 2, 3]))
# AssertionError: Series are different
# 
# Series length are different
# [left]:  2, Int64Index([0, 1], dtype='int64')
# [right]: 3, Int64Index([0, 1, 2], dtype='int64')

tm.assert_series_equal(pd.Series([1, 2, 3]), pd.Series([1, 2, 4]))
# AssertionError: Series are different
# 
# Series values are different (33.33333 %)
# [left]:  [1, 2, 3]
# [right]: [1, 2, 4]
```
## DataFrame
- Shape (size) 
- Dtype
- Index (same as above)
- Column (almost same as above, but different summary) 
- Values 

```
tm.assert_frame_equal(pd.DataFrame([[1, 2], [3, 4]]), pd.DataFrame([[1, 2, 3], [4, 5, 6]]))
# AssertionError: DataFrame are different
# 
# DataFrame shape (number of columns) are different
# [left]:  2, Int64Index([0, 1], dtype='int64')
# [right]: 3, Int64Index([0, 1, 2], dtype='int64')

tm.assert_frame_equal(pd.DataFrame([[1, 2], [3, 4]]), pd.DataFrame([[1, 2], [3, 4], [5, 6]]))
# AssertionError: DataFrame are different
# 
# DataFrame shape (number of rows) are different
# [left]:  2, Int64Index([0, 1], dtype='int64')
# [right]: 3, Int64Index([0, 1, 2], dtype='int64')

tm.assert_frame_equal(pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B']), pd.DataFrame([[1, 2], [3, 4]], columns=['a', 'b']))
# AssertionError: DataFrame.columns are different
# 
# DataFrame.columns values are different (100.0 %)
# [left]:  Index([u'A', u'B'], dtype='object')
# [right]: Index([u'a', u'b'], dtype='object')

tm.assert_frame_equal(pd.DataFrame([[1, 2], [3, 4]]), pd.DataFrame([[1, 2], [3, 5]]))
# AssertionError: DataFrame.iloc[1, :] are different
# 
# DataFrame.iloc[1, :] values are different (50.0 %)
# [left]:  [2, 4]
# [right]: [2, 5]
```


Labels:
name: Testing
description: pandas testing functions or related to the test suite

Comments:
@sinhrks What is the status of this? Is this ready for review? 
Does it implement the full description you gave in https://github.com/pydata/pandas/issues/10373#issuecomment-114851494

@jorisvandenbossche Rebased, and it is ready for review. I've updated the top description to show each outputs.

lgtm. only issue I would have is if an exception message were to actually fail because of a code issue in the exception code itself, but you are mostly testing that.

@jorisvandenbossche @shoyer @TomAugspurger Pls let me know if anything.

Let me merge this if there is no pointing out during the weekend.

@sinhrks lgtm

nice doc strings!

@sinhrks this is nice, e.g. (in this case its a sorting difference)

```
AssertionError: Series.index are different

Series.index values are different (96.66667 %)
[left]:  DatetimeIndex(['2000-02-09', '2000-01-20', '2000-01-10', '2000-01-24',
               '2000-01-07', '2000-02-11', '2000-01-25', '2000-01-03',
               '2000-02-03', '2000-02-01', '2000-02-07', '2000-01-19',
               '2000-02-02', '2000-01-14', '2000-01-31', '2000-01-05',
               '2000-02-10', '2000-01-06', '2000-01-18', '2000-01-11',
               '2000-01-21', '2000-01-13', '2000-01-28', '2000-01-17',
               '2000-02-08', '2000-01-27', '2000-01-12', '2000-02-04',
               '2000-01-04', '2000-01-26'],
              dtype='datetime64[ns]', freq=None, tz=None)
[right]: DatetimeIndex(['2000-01-03', '2000-01-04', '2000-01-05', '2000-01-06',
               '2000-01-07', '2000-01-10', '2000-01-11', '2000-01-12',
               '2000-01-13', '2000-01-14', '2000-01-17', '2000-01-18',
               '2000-01-19', '2000-01-20', '2000-01-21', '2000-01-24',
               '2000-01-25', '2000-01-26', '2000-01-27', '2000-01-28',
               '2000-01-31', '2000-02-01', '2000-02-02', '2000-02-03',
               '2000-02-04', '2000-02-07', '2000-02-08', '2000-02-09',
               '2000-02-10', '2000-02-11'],
              dtype='datetime64[ns]', freq='B', tz=None)
```